代码之家  ›  专栏  ›  技术社区  ›  Chuck Haines

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

  •  2
  • Chuck Haines  · 技术社区  · 14 年前

    我有一张桌子,上面有许多列,但是有两个相关的列:

    <代码> 到期金额
    反弹的到期金额 < /代码>

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

    <代码> 从表中选择*(到期金额>0或反弹金额>0) < /代码>

    对于SQL Server 2008,此表中最好的索引是包含索引中两列的索引,还是应该对每列分别放置一个索引?

    应付金额
    反弹的到期金额

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

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

    对于SQL Server 2008,此表中最好的索引是包含索引中两列的索引,还是应该对每列分别放置一个索引?

    4 回复  |  直到 14 年前
        1
  •  6
  •   KM.    14 年前

    索引不能用于或类似的。试试这个:

    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
    

    在到期金额上有一个索引,在反弹到期金额上有一个索引。

    重新设计你的桌子也许更好。在不知道您的业务逻辑或表的情况下,我想您可能有一个“bounched”Y/N或1/0 char/bit列,而只是一个“due_amount”列。在“到期金额”上添加索引,查询结果将是:

    SELECT * FROM table WHERE Due_Amount > 0
    

    您仍然可以区分反弹行和非反弹行。如果您同时需要有一个反弹和非反弹到期金额,这将不起作用。

        2
  •  1
  •   Tom H zenazn    14 年前

    我想你最好在每一列上都有一个索引。将它同时放在这两个列上不会比只放在第一列上有任何帮助,除非您有其他将使用复合索引的查询。

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

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

        3
  •  0
  •   Remus Rusanu    14 年前

    从技术上讲,可以对持久化计算列使用索引,并在查询中使用计算列而不是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建议的联合方法。

        4
  •  -2
  •   Koen    14 年前

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