我有一个包含一堆列的表,但两个相关的列是:
Due_Amount MONEY
Bounced_Due_Amount MONEY
我有一个SQL查询,如下所示
SELECT * FROM table WHERE (Due_Amount > 0 OR Bounced_Due_Amount > 0)
为SQL Server 2008放置此表的最佳索引是否是包含索引中的两列的索引,还是应该在每列上放置单独的索引?
答案 0 :(得分:6)
索引不能用于那样的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上有另一个索引。
重新设计你的桌子可能会更好。在不知道你的业务逻辑或表的情况下,我猜你可能会有一个“Bounced”Y / N或1/0 char / bit列,只有一个“Due_Amount”列。在“Due_Amount”上添加索引,查询将只是:
SELECT * FROM table WHERE Due_Amount > 0
你仍然可以区分Bounced或not row。如果您需要同时同时支付退回和未退回到期金额,则此功能无效。
答案 1 :(得分:1)
我的猜测是,每个列的索引都会更好。除非你有其他查询可以使用复合索引,否则将它放在两者上都不会有任何帮助。
最好的办法是尝试使用一列上的索引,另一列上的索引和两个索引(每列一个)进行查询。对每个测试(对于实际数据,而不是测试数据)进行一些测试,看看哪个最好。查看查询计划以了解原因。
根据特定数据(大小和基数),SQL Server可能最终使用一个,两个,甚至可能都不使用索引。确切知道的唯一方法是分别测试它们。
答案 2 :(得分:0)
从技术上讲,您可以在持久计算列上使用索引并在查询中使用计算列而不是OR条件,请参阅Creating Indexes on Computed Columns:
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 :(得分:-2)
特别是对于此查询,最好按照where子句中使用的顺序在两列上创建索引。否则可能不会使用索引。