WHERE FieldA = @P1 AND (FieldB = @P2 OR FieldC = @P2)
和
WHERE FieldA = @P1 AND FieldB = @P2
P1和P2是在UI中输入或来自外部数据源的参数.
> FieldA是一个int并且非常独特,意味着:表中只有两个,三个,四个不同的值,比方说20000行
> FieldB是一个varchar(20)并且“几乎”是唯一的,只有很少的行,其中FieldB可能具有相同的值
> FieldC是一个varchar(15),也是高度不同的,但不如FieldB
> FieldA和FieldB一起是唯一的(但不构成我的主键,这是一个带有聚簇索引的简单自动递增标识列)
我现在想知道定义索引以最好地加速这两个查询的最佳方法是什么.我应该用…定义一个索引
FieldB (or better FieldC here?) FieldC (or better FieldB here?) FieldA
…或更好的两个指数:
FieldB FieldA
和
FieldC FieldA
还是有其他更好的选择吗?什么是最好的方式和原因?
提前感谢您的建议!
编辑:
就像其他读者的信息一样:这是另一个已被删除的答案.实际上答案对我来说似乎非常有用.建议是创建两个索引(根据我上面的第二个选项)并使用两个select语句的UNION重新构造第一个查询(一个使用WHERE FieldA = @ P1 AND FieldB = @ P2,另一个使用WHERE FieldA = @ P1 AND FieldC = @ P2)而不是OR从两个索引中受益(OR运算符不是这种情况).
EDIT2:
使用OR并且未使用索引并且UNION更可取的声明似乎是错误的 – 至少根据我自己的测试(参见下面我自己的答案).
解决方法
>如果@ p2是varchar(15),那么你无法可靠地与FieldB进行比较,它是varchar(20)
>如果@ p2是varchar(20),则FieldC将转换为varchar(20)并且不使用索引(或者最好扫描它)
>如果@ p1只有2,3,4值那么为什么不使用tinyint并减少表/索引大小?
在解决此数据类型优先级问题之前,我不打算使用索引:这是在OR子句问题之上.
最后,列是唯一的或非唯一的:两者之间没有.统计数据在这里有助于选择性,但它无关紧要.
由于FieldA的选择性,我会将Remus回答的索引反转为FieldB,FieldA(和唯一)和FieldC,FieldA
注释后编辑:你无法比较使用@ p2和使用常量字符串.