2015-04-01 39 views
1

我们有一个大约300万行的表(T)和两个INT列(ID1和ID2),它们一起被设置为复合聚集键。如何减少具有复合索引的表上的扫描计数?

在存储过程早期,我们创建一个表变量(@A),它由一列INT组成。

慢速查询是以下

SELECT T.ID1, T.ID2 
FROM T 
INNER JOIN @A AS A 
ON A.ID = T.ID1 

@A将只有几百行,T包含了几百万行。问题是T得到了几百个扫描计数。我不知道如何让它消失。

我试图在包含列ID1和ID2的T上创建另一个索引,但它没有帮助(执行计划程序显示使用了新索引)。

可以做些什么来减少表T上的扫描计数?

(我们使用SQL Server 2014网络版)

+0

索引中的列以什么顺序排列? – idstam 2015-04-01 17:33:06

+0

订单是ID2,ID1。这是否重要? – Sten 2015-04-01 17:43:17

回答

0

尝试创建一个包含(包括指数):

create index idx_t_id1 on t(id1) include id2 

这将使您的查询找到它的索引页需要的一切,将不必在主表中搜索。顺便说一下,表t上的聚集索引?

+0

这就是我试过的索引(很差)。扫描计数仍然在数百。是的,T上有一个聚集索引。聚集索引包括ID1 + ID2。 – Sten 2015-04-01 17:42:10

+0

如果在@a中有300行,您正在执行内部连接,并且如果@a和t之间存在一对一匹配,则SQL Server将从t读取300行。我错过了什么? – 2015-04-01 17:57:45

+0

看起来像答案是,我是在一个旧的假设下扫描计数意味着全表扫描。我做了Google搜索,现在意识到它仅仅意味着表访问 - 所以问题并没有出现在第一位。但是,如果您的索引建议不在其中,那么您的索引建议显然会是什么答案。所以我将你的答案标记为正确答案。为此事道歉。 – Sten 2015-04-02 08:34:20

0

你可以尝试措辞查询是这样的:

select a.id as id1, 
     (select t.id2 
     from t 
     where t.id1 = a.id 
     ) as id2 
from @a a; 

这应该扫描@a和使用索引的查找。

有两点需要注意:

  • 如果可以有多个匹配,使用cross apply代替。
  • 如果可能没有匹配,并且您想要筛选行,请使用子查询或CTE。