我有一个表,其中有很多列,但两个相关的列是:
Due_Amount MONEY
Bounced_Due_Amount MONEY
我有一个如下所示的 SQL 查询
SELECT * FROM table WHERE (Due_Amount > 0 OR Bounced_Due_Amount > 0)
对于 SQL Server 2008,在此表上放置的最佳索引是包含索引中的两列的索引,还是应该在每一列上放置单独的索引?
索引不能用在这样的 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
您仍然可以区分退回行或未退回行。 如果您需要同时拥有退回的应付金额和未退回的到期金额,则此方法将不起作用。
我的猜测是,在每个单独的列上都有一个索引会更好。除非您有其他使用复合索引的查询,否则将其放在两者上不会比仅将其放在第一列上有任何帮助。
最好的选择是尝试使用一个列上的索引、另一列上的索引和两个索引(每列一个)的查询。对每个数据进行一些测试(使用真实数据,而不是测试数据),看看哪个效果最好。查看查询计划以了解原因。
根据具体数据(大小和基数),SQL Server 最终可能会使用一个索引、两个索引,甚至可能都不使用索引。唯一确定的方法就是对它们进行测试。
从技术上讲,您可以在持久计算列上建立索引,并在查询中使用计算列而不是 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 方法。
特别对于此查询,最好按照它们在 where 子句中使用的顺序在两列上创建索引。否则索引可能无法使用。