[英]Why Optimizer Does Not Use Index Seek on Join
我不知道为什么下面的SELECT
语句(下面)不使用索引搜索,而是使用索引扫描。 仅仅是因为行数太少还是我错过了什么?
测试数据:
-- 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
执行计划:
优化器有几种方法可以做乔恩: nested loops, hash match or merge join
联接(您的情况),并且可能是另一种方法。 根据您的数据:行数,现有索引和统计ID确定哪个更好。
在您的示例中,优化器假定存在多对多关系。 并且您有两个表都被此字段soret(索引)。
为什么合并联接? -从逻辑上讲-并行浏览两个表。 服务器将只需要执行一次。
为了进行所需的seek
,服务器必须一次移动第一个表,并且必须多次在第二个表中进行查找,因为所有记录在另一个表中都有匹配项。 服务器将根据需要读取所有记录。 而且,使用搜寻时没有任何利润(1000次搜寻比遍历1000条记录的一个简单循环还要困难)。
如果要seek
,请在查询中添加一些没有匹配项和where
子句的记录。
UPD
甚至添加简单
where j.ID = 1
给你seek
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.