我想知道为什么以下SELECT
语句(下面)不使用Index Seek,而是使用Index Scan。是因为行数太小还是我错过了什么?
测试数据:
-- Init Tables
IF OBJECT_ID ( 'tempdb..#wat' ) IS NOT NULL
DROP TABLE #wat;
IF OBJECT_ID ( 'tempdb..#jam' ) IS NOT NULL
DROP TABLE #jam;
CREATE TABLE #wat (
ID INT IDENTITY(1,1) NOT NULL,
Name VARCHAR(15) NOT NULL,
Den DATETIME NOT NULL
)
CREATE TABLE #jam (
ID INT IDENTITY(1,1) NOT NULL,
Name VARCHAR(15) NOT NULL
)
-- Populate Temp Tables with Random Data
DECLARE @length INT
,@charpool VARCHAR(255)
,@poolLength INT
,@RandomString VARCHAR(255)
,@LoopCount INT
SET @Length = RAND() * 5 + 8
SET @CharPool = 'abcdefghijkmnopqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ23456789'
SET @PoolLength = LEN(@CharPool)
SET @LoopCount = 0
SET @RandomString = ''
WHILE (@LoopCount < 500)
BEGIN
INSERT INTO #jam (Name)
SELECT SUBSTRING(@Charpool, CONVERT(int, RAND() * @PoolLength), 5)
SET @LoopCount = @LoopCount + 1
END
-- Insert Rows into Second Temp Table
INSERT INTO #wat( Name, Den )
SELECT TOP 50 Name, GETDATE()
FROM #jam
-- Create Indexes
--DROP INDEX IX_jedna ON #jam
--DROP INDEX IX_dva ON #wat
CREATE INDEX IX_jedna ON #jam (Name) INCLUDE (ID);
CREATE INDEX IX_dva ON #wat (Name) INCLUDE (ID, Den);
-- Select
SELECT *
FROM #jam j
JOIN #wat w
ON w.Name = j.Name
执行计划:
答案 0 :(得分:0)
优化器有几种方法可以做jons:nested loops, hash match or merge join
(你的情况),可能是另一种方法。
根据您的数据:行数,现有索引和统计ID决定哪一个更好。
优化器假定存在多对多关系。并且你有两个表由这个字段soret(索引)。
为什么合并加入? - 逻辑上 - 平行移动两个表。而服务器只需要这样做一次。
要根据需要制作seek
,服务器必须先移动第一个表,并且必须多次在第二个表中进行搜索,因为所有记录在另一个表中都有匹配。如果他寻求,服务器将读取所有记录。使用搜索时没有任何利润(1000寻求甚至比通过1000条记录的简单循环更加困难)。
如果您希望seek
在查询中添加一些没有匹配和where
子句的记录。
<强> UPD 强>
甚至添加简单的
where j.ID = 1
为您提供seek