我有一个非常奇怪的问题。
我在SQL Server 2008 R2中运行了这样的查询:
SELECT TOP (20) *
FROM MyTable
WHERE a = 0
AND b = 0
AND c = 0
在MyTable上使用我的索引
但这个没有:
SELECT TOP (20) *
FROM MyTable
WHERE a = 0
OR b = 0
OR c = 0
我想在我的程序中执行第二个查询。如何更改第二个查询以使用索引?
索引是:
CREATE NONCLUSTERED INDEX [MyIndex] ON [dbo].[MyTable] (
[a] ASC,
[b] ASC,
[c] ASC
)
WITH (
PAD_INDEX = OFF,
STATISTICS_NORECOMPUTE = OFF,
SORT_IN_TEMPDB = OFF,
IGNORE_DUP_KEY = OFF,
DROP_EXISTING = OFF,
ONLINE = OFF,
ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON
) ON [PRIMARY]
答案 0 :(得分:5)
对于条件之间or
的查询,您不能使用该索引。试想一下:任何一个值都可以匹配,因此索引匹配不能保证没有其他记录符合该条件。
这就像运行单独的搜索然后将它们匹配在一起一样。
答案 1 :(得分:0)
为了使用Index,SQL-Server会检查很多东西
1)如果过滤器是SARG。
2)指数使用似然比(唯一记录数:总记录数)
3)没有要获取的记录(如果记录较少,可以使用索引或者表扫描。因为sql-server发现扫描整个表比查找和使用索引更容易记录数量巨大。)
4)在您的查询中,因为您正在使用OR
,所以记录数量增加,在哪种情况下,sql-server发现扫描整个表比查找/更容易使用索引。如果是AND
,则使用索引的可能性会增加。
答案 2 :(得分:0)
其他回答者说的是真的。但是,您可以使用技巧:
SELECT TOP (20) *
(
select TOP(20) *
FROM MyTable
WHERE a = 0
union
SELECT TOP(20) *
FROM MyTable
WHERE b = 0
union
SELECT TOP(20) *
FROM MyTable
WHERE c = 0
)
每个子查询都可以使用单独的索引。所以,现在您只需要3个独立的索引(前导列分别为a,b和c),您就可以了。