我正在sql server中准备一个存储过程。基本上,我这里有两个表,表a和表b,这两个表是连接在一起的 Col4
. 这个存储过程将根据表b中的属性过滤表a,比如 Col41
以及 Col42
在 where
条款(两者) Col41
以及 Col42
属于 float
数据类型)。
表a:
Col1 Col2 Col3 Col4
Row1 ** ** ** **
Row2 ** ** ** **
表b:
Col5 Col4 Col41 Col42
Row1 ** ** ** **
Row2 ** ** ** **
这两个表中有很多记录,因此我计划使用非聚集索引来帮助查询(两个表都将其第一列设置为主键)。
当我如下图所示创建了这个非聚集索引,然后在存储过程(临时索引)中使用后将其丢弃时,性能非常好。
CREATE NONCLUSTERED INDEX IX_1 ON tableB (Col41, Col42)
DROP INDEX IF EXISTS IX_1 ON tableB
但是,如果我直接将相同的非聚集索引添加到tableb(永久索引),或者右键单击tableb的index文件夹,或者运行下面的代码,性能会差得多。似乎即使创建了非聚集索引,也没有使用它。
CREATE NONCLUSTERED INDEX IX_1 ON tableB (Col41, Col42)
不明白为什么运行结果是这样的。有人能告诉我怎么解决这个问题吗?谢谢。
2条答案
按热度按时间nuypyhwy1#
对于你的情况,你需要两个索引-
如果您仍然看到问题,如alwayslearning所述,请检查执行计划,它可以告诉您如何访问数据的详细信息。
2o7dmzc52#
正如@mitch-wheat提到的,添加索引并不能确保它总是被使用。还有一件事,不要在存储过程中创建和删除索引,除非是在临时表上创建索引。创建索引是一项代价高昂的操作。最好在开发代码之外单独做。
这取决于具体查询的查询和索引的选择性。有一种称为“临界点”的方法,它将检查使用索引还是直接从表中读取对特定查询都有好处。阅读更多关于引爆点金伯利特里普
关于您的查询,当您告诉col41和col42总是要用于filter,并且要使用col4连接tablea时,我建议您像下面那样覆盖索引,以使索引可查找。如果组合是唯一的,请创建唯一索引。
但是,这里您必须看到列的选择性,才能看到列的顺序:col41和col42。选择度较高的列位于左侧,选择度较低的列位于右侧。
要查找列的选择性,请参阅列统计信息。将有第二个结果集,它告诉列的密度。它越小,柱的选择性就越强。
另外,在tablea上为col4创建索引。如果列是唯一的,请创建唯一索引。
注意:以上也不能保证索引总是被使用。如果看不到执行计划和实际查询,很难判断。上述准则也专门针对一个查询。我建议您看看,是否可以将上述索引与现有查询合并到其他索引,以减少表上的索引占用。