何时需要以下内容:
create index i_t_a_b on t(a,b);
create index i_t_b_a on t(b,a);
当您想要最大检索速度并且在连接或 where 条件中都有两列时,但有时列 a 具有更高的选择性,有时列 b 具有更高的选择性,并且您希望从单个索引中利用这一事实。
此外,我认为您的数据大小/机器性能的比率应该很高,同时您必须(猜测)愿意将任何改进称为必要性(即使只有几个百分比)。
尽管如此,经验告诉我们,事情取决于很多因素。使用特定的 RDBMS 和应用程序环境,您可以更好地运行自己的基准测试。
编辑:关于复合索引的进一步解释。来自维基百科:
“在索引定义中列出列的顺序很重要。可以仅使用第一个索引列来检索一组行标识符。但是,(在大多数数据库上)检索是不可能或有效的仅使用第二个或更大索引列的行标识符集。
例如,想象一个电话簿,它首先按城市,然后按姓氏,然后按名字组织。如果给定城市,您可以轻松提取该城市的所有电话号码列表。但是,在此电话簿中查找给定姓氏的所有电话号码将非常繁琐。您必须在每个城市的部分中查找具有该姓氏的条目。 "
Wikipedia 的解释可能过于简化,但它为您提供了基本概念(类比请记住,电话簿通常具有聚集索引,而这不是您的通用数据库索引)。
根据索引的大小、数据结构的大小、可用内存和索引第一列的选择性,使用错误排序的索引可能比使用表扫描便宜得多。
啊,只是想到了一个与您正在寻找的示例更好的类比想象一本不错的教科书,它会有包含章节和子章节的目录以及它们所在的页数(这是一个非聚集索引,它保存指针到数据记录 - 页)。现在假设教科书是基于 SQL-92 标准的,那么 TOC 中的大部分术语都是 SQL 术语(保持这个假设)。您还会在本书的末尾有另一个索引,它将按字母顺序列出所有有趣的术语(让我们假设主要章节名称)和页码。
对于诸如“告诉我出现 DISTINCT 的所有章节”之类的问题,您将使用第二个索引。(因为后面字段的选择性高)
对于诸如“告诉我出现在第一章下的术语的数量”之类的问题,您将使用 TOC
因此,对于诸如“DML 章节中是否描述了 SELECT”之类的问题?您可以使用任何一个索引。(因为这两个字段的选择性都很高)但是,如果 DML 本身的 TOC 有 3 页长,并且索引中的 SELECT 条目只有 15 行,您可能会转到第二行,这就是您从两者中受益的示例索引。
现在,如果您认为这太过分了,请考虑使用已扫描的国会图书馆数据库。:)
正如我之前所说,所有的计划都很好,但最后一定要运行你自己的基准测试。
我认为没有任何实际情况需要您这样做。
当您的表具有更多列a
并且b
不是唯一的并且您需要以下两个查询的高性能时,这可能是有意义的:
Select Max(b) From t Where a=1 --# Would use i_t_a_b
和
Select Max(a) From t Where b=1 --# Would use i_t_b_a
假设您的表格如下所示:
a b c d e
- - - - -
0 8 x x x
0 9 x x x
1 8 x x x
1 9 x x x
i_t_a_b
看起来像这样:
0
8
9
1
8
9
i_t_b_a
看起来像这样:
8
0
1
9
0
1
Select Max(b) From t Where a=1
将不得不深入研究8
并找到所有带有. 这仍然比全表扫描快得多(也必须读取所有内容),但不如使用.9
i_t_b_a
a=1
x
i_t_a_b