代码之家  ›  专栏  ›  技术社区  ›  David Clarke

为什么SQLServerCE查询执行表扫描,这是一个问题吗?

  •  4
  • David Clarke  · 技术社区  · 15 年前

    我正在尝试优化在Windows移动设备上运行的SQLServerCE数据库的查询。查询用于根据不再从其他表中引用来标识要删除的行。原始查询使用 明显的

    SELECT TestGroupId, TestNameId, ServiceTypeId
    FROM ServiceTypeInspection
    WHERE ServiceTypeId NOT IN
        (SELECT DISTINCT ServiceTypeId
         FROM PurchaseOrder)
    

    存在 而是通过:

    SELECT TestGroupId, TestNameId, ServiceTypeId
    FROM ServiceTypeInspection AS STI
    WHERE NOT EXISTS
        (SELECT PurchaseOrderId
         FROM PurchaseOrder AS PO
         WHERE (ServiceTypeId = STI.ServiceTypeId))
    

    但后来我也找到了关于SO和MSDN的建议,用 听起来很有希望:

    SELECT TestGroupId, TestNameId, STI.ServiceTypeId ServiceTypeId
    FROM ServiceTypeInspection STI
    LEFT JOIN PurchaseOrder PO ON STI.ServiceTypeId = PO.ServiceTypeId
    WHERE PO.ServiceTypeId IS NULL
    

    当我将这些查询作为显示执行计划的批处理运行时,相对于原始查询的批处理的成本是21% 不存在 左连接 占比68%。SSM并不表示有任何索引丢失,但最快, 不存在 服务类型ID 在两张桌子上。我是否正确地阅读了执行计划的输出,在这种情况下 不存在 版本是最好的方法吗?表扫描是潜在的瓶颈还是对于非唯一索引来说这是正常的?

    表定义为:

    CREATE TABLE [PurchaseOrder](
    [PurchaseOrderId] [uniqueidentifier] NOT NULL,
    [ServiceTypeId] [nvarchar](8) NOT NULL,
    CONSTRAINT [PK_PurchaseOrder] PRIMARY KEY
    (
      [PurchaseOrderId]
    )
    );
    
    CREATE TABLE [ServiceTypeInspection](
    [TestGroupId] [int] NOT NULL,
    [TestNameId] [nvarchar](10) NOT NULL,
    [ServiceTypeId] [nvarchar](8) NOT NULL,
    CONSTRAINT [PK_ServiceTypeInspection] PRIMARY KEY
    (
      [TestGroupId],[TestNameId]
    )
    );
    
    CREATE INDEX IX_PurchaseOrder_ServiceTypeId ON [PurchaseOrder] (ServiceTypeId);
    CREATE INDEX IX_ServiceTypeInspection_ServiceTypeId ON [ServiceTypeInspection] (ServiceTypeId);
    
    1 回复  |  直到 15 年前
        1
  •  1
  •   Mitch Wheat    15 年前

    我的猜测是,与表大小相比,您的NC索引的大小相对较大(大主键,我假设它也是默认的聚集索引,这意味着您有较大的NC索引),因此优化者决定表扫描。

    另外,如果索引 IX_PurchaseOrder_ServiceTypeId IX_ServiceTypeInspection_ServiceTypeId 选择性小于10%时,乐观者可能不会使用它们。