如果我有一个包含三列的索引,但我有两个查询,一个仅针对两列,一个针对三列 - 两者都会使用相同的索引吗?

问题描述 投票:0回答:1

我有一个对象,其中包含

IsDeleted
RealmIntID
作为列,这些列将始终出现在该对象的每个查询中(以及一些分页参数)。我们不想返回软删除的对象,也不想返回不在领域中的对象。

还有另一个查询,我需要检查

IsDeleted
RealmIntID
和显示名称(对于搜索框类型查询)。我也想正确地对此进行索引。如果可能的话,我想避免使用两个索引,因为我知道每个新索引都会降低我的性能。

[IsDeleted, RealmIntId, DisplayName]
上的索引可以满足这两个查询吗?我假设第一个查询只会查询索引的前两列,而第二个查询将使用所有三列。

sql-server t-sql indexing query-optimization
1个回答
0
投票

克雷格·弗里德曼(Craig Freedman)有一篇精彩的博客(链接在底部),其中有一些很好的例子..引用了相关部分以避免链接失效

单列索引:
假设我们在列“a”上有一个单列索引。我们可以使用这个索引来查找这些谓词:

a = 3.14
a > 100
a between 0 and 99
a like ‘abc%’
a in (2, 3, 5, 7)

多列索引:

多列索引稍微复杂一些。对于多列索引,键的顺序很重要。它确定索引的排序顺序,并影响 SQL Server 可以使用索引评估的查找谓词集。

假设我们在“a”和“b”列上有一个两列索引。 我们还可以使用它来查找这些附加谓词:

a = 3.14 and b = ‘pi’
a = ‘xyzzy’ and b <= 0

我们无法使用索引来查找下一组谓词,因为我们甚至无法在 a 列上进行查找。在这些情况下,我们必须使用不同的索引(例如,b 列是前导列的索引),或者我们必须使用带有残差谓词的扫描。

b = 0
a + 1 = 9 and b between 1 and 9
a like ‘%abc’ and b in (1, 3, 5)

另请注意,书签查找可能会跨越临界点,并可能导致扫描

现在回答您的问题“[IsDeleted、RealmIntId、DisplayName] 上的索引是否可以满足这两个查询?”..

这取决于您的查询和 select 语句中的列,以及它们是否是索引的一部分。即使 select 中的列是索引的一部分,您也可以查看上面的示例来了解什么类型的索引适合查询。

我的一般经验法则是,如果查询更频繁并且需要快速完成,我将创建索引。如果查询很少,我不会用额外的索引给我的表带来负担

参考资料:
https://learn.microsoft.com/en-us/archive/blogs/craigfr/seek-predicates
https://www.sqlskills.com/blogs/kimberly/why-arent-those-nonclustered-indexes-being-used/

© www.soinside.com 2019 - 2024. All rights reserved.