为什么优化器不使用索引寻求加入

时间:2016-06-21 12:42:29

标签: sql sql-server performance indexing sql-server-2014

我想知道为什么以下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

执行计划:

enter image description here

1 个答案:

答案 0 :(得分:0)

优化器有几种方法可以做jons:nested loops, hash match or merge join(你的情况),可能是另一种方法。 根据您的数据:行数,现有索引和统计ID决定哪一个更好。

在您的示例中,

优化器假定存在多对多关系。并且你有两个表由这个字段soret(索引)。

为什么合并加入? - 逻辑上 - 平行移动两个表。而服务器只需要这样做一次。

要根据需要制作seek,服务器必须先移动第一个表,并且必须多次在第二个表中进行搜索,因为所有记录在另一个表中都有匹配。如果他寻求,服务器将读取所有记录。使用搜索时没有任何利润(1000寻求甚至比通过1000条记录的简单循环更加困难)。

如果您希望seek在查询中添加一些没有匹配和where子句的记录。

<强> UPD

甚至添加简单的

where j.ID = 1

为您提供seek