我有两个语句返回相同的结果,但产生不同的执行计划。
任何人都可以解释原因吗?
CREATE TABLE OrderDetails (intOrderId int, intItemId int, dtOrderDate Datetime, intQty int, intPrice int, intDiscount int)
GO
CREATE CLUSTERED INDEX CI_OrderId ON OrderDetails(intOrderId)
GO
CREATE NONCLUSTERED INDEX NCI_ItemId ON OrderDetails(intItemId)
GO
-- Populate Data
SET NOCOUNT ON
DECLARE @i int
SET @i =10
WHILE @i < 100000
BEGIN
INSERT INTO OrderDetails
VALUES (@i, round(rand()*9999,0)+1, getdate() - round(rand()*999,0), round(rand()*99,0)+1, round(rand()*9999,0)+1, round(rand()*99,0)+1)
SET @i = @i + 1
END
GO
-- Check Execution Plans
-- NCI SEEK
SELECT intOrderId, intItemId
FROM OrderDetails
WHERE intItemId = 600 * 10
-- NCI SCAN
SELECT intOrderId, intItemId
FROM OrderDetails
WHERE intItemId/10 = 600
答案 0 :(得分:2)
有两个原因......
第一条评论的含义是,优化工具可以看到您正在对intItemId
执行某些操作,但它不会尝试找到快捷方式。相反,它必须在每一行上执行/10
以查看结果。
(它不知道6000/10 = 600但是5999没有。所以它会在每一行上尝试。)
这与第二个原因有关。您的问题意味着您希望第二个查询只返回行intItemId = 6000
。但由于整数运算,6001/10
到6009/10
都等于600
。因此,当您进行整数运算时,x/10=y
变为x=y*10
的代数操作无效。这是优化者不尝试的部分原因。
简而言之:每当您以虚拟 任何 方式操作索引字段时,您将阻止使用索引并获取扫描而不是搜索。 / p>