用于 SQL Server 中 OR 语句的最佳索引

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

我有一个表,其中有很多列,但两个相关的列是:

Due_Amount MONEY
Bounced_Due_Amount MONEY

我有一个如下所示的 SQL 查询

SELECT * FROM table WHERE (Due_Amount > 0 OR Bounced_Due_Amount > 0)

对于 SQL Server 2008,在此表上放置的最佳索引是包含索引中的两列的索引,还是应该在每一列上放置单独的索引?

sql-server sql-server-2008 indexing
4个回答
8
投票

索引不能用在这样的 OR 上。试试这个:

SELECT * FROM table WHERE Due_Amount > 0
UNION ALL  
SELECT * FROM table Bounced_Due_Amount > 0
--use "UNION" if Due_Amount and Bounced_Due_Amount could both >0 at any one time

在 Due_Amount 上有一个索引,在 Bounced_Due_Amount 上有另一个索引。

重新设计你的桌子可能会更好。 在不了解您的业务逻辑或表的情况下,我猜测您可能有一个“退回”Y/N 或 1/0 字符/位列,并且只有一个“Due_Amount”列。在“Due_Amount”上添加索引,查询将是:

SELECT * FROM table WHERE Due_Amount > 0

您仍然可以区分退回行或未退回行。 如果您需要同时拥有退回的应付金额和未退回的到期金额,则此方法将不起作用。


1
投票

我的猜测是,在每个单独的列上都有一个索引会更好。除非您有其他使用复合索引的查询,否则将其放在两者上不会比仅将其放在第一列上有任何帮助。

最好的选择是尝试使用一个列上的索引、另一列上的索引和两个索引(每列一个)的查询。对每个数据进行一些测试(使用真实数据,而不是测试数据),看看哪个效果最好。查看查询计划以了解原因。

根据具体数据(大小和基数),SQL Server 最终可能会使用一个索引、两个索引,甚至可能都不使用索引。唯一确定的方法就是对它们进行测试。


1
投票

从技术上讲,您可以在持久计算列上建立索引,并在查询中使用计算列而不是 OR 条件,请参阅在计算列上创建索引

alter table [table] add Max_Due_Amount as
   case 
    when Due_Amount > Bounced_Due_Amount the Due_Ammount
    else Bounced_Due_Amount
   end
   persisted;
go

create index idxTableMaxDueAmount on table (Max_Due_Amount );
go

SELECT * FROM table WHERE Max_Due_Amount > 0;

但总的来说,我建议使用 KM 建议的 UNION 方法。


-3
投票

特别对于此查询,最好按照它们在 where 子句中使用的顺序在两列上创建索引。否则索引可能无法使用。

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