我把问题缩小到最小的例子 . 我应该为我想要运行的实际查询中的顶级选择更多列 .

查询:

SELECT [AspNetUsers].Id
FROM [Trade_US_PC]
INNER JOIN [AspNetUsers] ON ([Trade_US_PC].[TraderUserID] = [AspNetUsers].[Id])
WHERE [Trade_US_PC].[ID] IN (SELECT TOP 10 [Trade_US_PC].[ID] 
                             FROM [Trade_US_PC]
                             INNER JOIN [Item] ON ([Trade_US_PC].[ItemID] = [Item].[ID])
                             WHERE ([Trade_US_PC].[ItemTraitsID] = 14)
                             ORDER BY [Item].[Name_EN])

IN (SELECT ID) 技巧是我从MySQL学到的东西,在某些情况下可以加速 ORDER BY . 但它肯定不会在这里发挥作用 .

此查询已运行两个多小时,仍在执行中 .

查询中的所有列都已编制索引 . 所有ID都是主键群集索引

查询计划:

enter image description here

这是有趣的部分:子查询( SELECT TOP 10 ...)只需要1秒即可运行 .

查询计划:

enter image description here

IO Stat:

(10行受影响)表'工作文件' . 扫描计数0,逻辑读取0,物理读取0,预读取读取0,lob逻辑读取0,lob物理读取0,lob预读读取0.表'工作表' . 扫描计数0,逻辑读取0,物理读取0,预读取读取0,lob逻辑读取0,lob物理读取0,lob预读读取0.表'项' . 扫描计数1,逻辑读取38,物理读取0,预读取读取0,lob逻辑读取0,lob物理读取0,lob预读读取0.表'Trade_US_PC' . 扫描计数1,逻辑读取2443,物理读取0,预读取读取0,lob逻辑读取0,lob物理读取0,lob预读读取0 .

如果我用从子查询返回的10个ID替换子查询,则整个查询也需要1s才能运行 .

查询计划:

enter image description here

IO Stat:

(10行受影响)表'AspNetUsers' . 扫描计数0,逻辑读取20,物理读取0,预读取读取0,lob逻辑读取0,lob物理读取0,lob预读读取0.表'Trade_US_PC' . 扫描计数10,逻辑读取30,物理读取0,预读读取0,lob逻辑读取0,lob物理读取0,lob预读读取0 .

最后,如果我摆脱 IN(SELECT ID) 技巧,它也需要1秒才能运行

SELECT top 10 [AspNetUsers].Id
FROM [Trade_US_PC]
INNER JOIN [AspNetUsers] ON ([Trade_US_PC].[TraderUserID] = [AspNetUsers].[Id])
INNER JOIN Item on Item.ID = ItemID
WHERE [Trade_US_PC].[ItemTraitsID] = 14 
ORDER BY [Item].[Name_EN]

查询计划:
enter image description here

IO Stat:

(10行受影响)表'项目' . 扫描计数0,逻辑读取3716,物理读取0,预读读取0,lob逻辑读取0,lob物理读取0,lob预读读取0.表'Trade_US_PC' . 扫描计数44,逻辑读取990999,物理读取0,预读读取0,lob逻辑读取0,lob物理读取0,lob预读读取0.表'AspNetUsers' . 扫描计数1,逻辑读取2,物理读取0,预读取读取0,lob逻辑读取0,lob物理读取0,lob预读读取0 .

Trade_US_PC 表中大约有400k行, Item 表中有8k行, AspNetUsers 表中有50行

我在SQL Server 2012和LocalDB(16G ram SSD)中尝试了这个 . 两者都产生相同的结果 . 在执行查询时,CPU使用率约为10-15%,0MB磁盘IO和ram使用率与未运行此查询相同 .
知道为什么会这样吗?