【发布时间】:2018-10-15 03:54:26
【问题描述】:
我有这个练习的测试表:
CREATE DATABASE QueryTest
GO
USE QueryTest
CREATE TABLE Person
(
ID INT IDENTITY (1,1),
FirstName NVARCHAR(50),
SurName NVARCHAR(50),
Salary MONEY
)
INSERT INTO Person
SELECT TOP 2000
FirstName,
LastName,
RAND(CAST( NEWID() AS varbinary)) *100000
FROM [AdventureWorks2014].[Person].[Person]
ORDER BY NEWID()
CREATE INDEX IX_Person_Salary ON Person
(
Salary
)
如果我运行以下命令,我会得到一个表扫描,这是我所期望的
SELECT Salary FROM Person
如果我这样做,我会得到一个索引搜索 - 再次完全符合预期,
SELECT Salary FROM Person WHERE Salary > 270
但是,如果我这样做:
SELECT Salary FROM Person WHERE Salary > 0
我得到一个索引搜索(尽管它返回了表中的所有行
此外,如果我运行
SELECT Salary FROM Person
SELECT Salary FROM Person WHERE Salary > 0
在同一批次中,它们都是批次的 50%
这里发生了什么? 如果将返回所有行,为什么当 WHERE 子句存在时 SQL Server 使用查找?
为什么索引查找与索引扫描的成本相同?
我的印象是 SQL Server 会使用其统计信息来估计要返回的行数,然后相应地计划其执行。统计数据会告诉它 >0 是所有行,因此在这种情况下扫描成本会更低?
【问题讨论】:
-
您是否在执行之间清除缓冲区并计划缓存?也许你有"forced parametrization option"。
-
我认为这是意料之中的,因为引擎仍然需要比较薪水的值来查看它是否大于零,就像它与 270 比较时一样
-
不应该吗?即使它返回所有内容,它仍然是一个搜索,因为它仍然需要解析索引。由于查找只触及符合条件的行并解析所有包含这些行的行,因此成本与符合条件的行数和解析数成正比,而不是与表中的总行数成正比。即使所有东西都被拉出,情况也是如此。除非我完全脱离基地。
-
我的印象是 SQL Server 会使用其统计信息来估计要返回的行数,然后相应地计划其执行。统计数据会告诉它 >0 是所有行,因此在这种情况下扫描成本会更低?
-
如果你有 100k 行和最新更新的统计数据会有什么不同吗?
标签: sql sql-server-2014 sql-execution-plan