为什么SQLServerCE查询执行表扫描并且是一个问题?
我试图优化对Windows Mobile设备上运行的SQLServerCE数据库的查询。 该查询用于根据不再从其他表中引用的行来标识要在一个表中删除的行。 原始查询使用DISTINCT来标识匹配的行:
SELECT TestGroupId, TestNameId, ServiceTypeId
FROM ServiceTypeInspection
WHERE ServiceTypeId NOT IN
(SELECT DISTINCT ServiceTypeId
FROM PurchaseOrder)
快速谷歌建议使用EXISTS,而不是通过:
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%,NOT EXISTS版本为11%,LEFT JOIN负责68%的余额。 SSMS并不指示有任何缺失的索引,但最快,在表扫描中NOT EXISTS查询的成本为25%。 我在两个表中的ServiceTypeId上都有非唯一索引。 我是否正确阅读执行计划的输出结果,在这种情况下,NOT EXISTS版本是最好的方法? 该表是否扫描了潜在的瓶颈或对于非唯一索引是否正常?
表格定义是:
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);
我的猜测是,与表格大小相比,您的NC索引的大小相对较大(大的主键,我假设它也是默认的聚集索引,这意味着您有大的NC索引),所以优化器正在决定表格扫描。
另外,如果索引IX_PurchaseOrder_ServiceTypeId
和IX_ServiceTypeInspection_ServiceTypeId
选择性少于10%,那么优化器可能不会使用它们。
上一篇: Why is SQLServerCE query performing a table scan and is it an issue?
下一篇: SQL Server 2005, wide indexes, computed columns, and sargable queries