复合索引在MySQL中有方向吗?

时间:2010-03-23 13:58:01

标签: mysql covering-index

以下什么时候需要:

create index i_t_a_b on t(a,b);

create index i_t_b_a on t(b,a);

2 个答案:

答案 0 :(得分:2)

当你想要最大的检索速度并且在连接或条件中有两列时,但有时列a具有更高的选择性,有时列b具有更高的选择性,并且你想要从单个索引中利用这个事实。

此外,我认为您的机器数据大小/性能比率应该非常高,同时您必须(猜测)愿意将任何改进称为必要(即使只有几个百分比)。

但是,经验告诉我们,事情取决于很多因素;使用特定的RDBMS和应用程序环境,您最好运行自己的基准测试。

编辑: 关于综合指数的进一步说明 来自wikipedia
“列在索引定义中列出的顺序很重要。可以仅使用第一个索引列检索一组行标识符。但是,检索它是不可能的或有效的(在大多数数据库上)仅使用第二个或更大索引列的行标识符集 例如,假设一个电话簿首先由城市组织,然后按姓氏组织,然后按名字组织。如果您获得了城市,则可以轻松提取该城市的所有电话号码列表。但是,在这本电话簿中找到给定姓氏的所有电话号码是非常繁琐的。您必须在每个城市的部分中查找具有该姓氏的条目。“

维基百科的解释可能过于简化,但它为您提供了基本的想法(因为类比记住,电话簿通常有聚集索引,而不是您的通用数据库索引)。

根据索引的大小与数据结构的大小与索引第一列的可用内存与选择性的关系,使用错误排序的索引然后使用表扫描可能要便宜得多。

啊,只是想到一个更好的类比,你正在寻找一个例子 想象一本不错的教科书,它将包含章节和子章节的目录以及它们所在页面的数量(这是一个非聚集索引,其中包含指向数据记录的指针 - 页面)。 现在假设教科书是基于SQL-92标准的,那么TOC中的大多数术语都是SQL术语(确实持有这个假设)。 您还可以在本书末尾添加另一个索引,该索引将按字母顺序列出所有有趣的术语(让我们假设主要章节名称)和页码。

对于诸如此类的问题 '告诉我DISTINCT出现的所有章节'你会使用第二个索引。 (因为后期字段的选择性很高)

对于诸如此类的问题 '告诉我第一章中出现的术语数量'你将使用TOC

所以对于诸如此类的问题 '在DML章节中描述了SELECT吗?'您可以使用任一索引。 (因为两个字段的选择性都很高) 但是,如果DML的TOC本身长3页,而索引中的SELECT条目只有15行,那么你可能会转到第二行,这就是你从两个索引中受益的一个例子。

现在,如果您认为太过牵强,请考虑扫描的会议库数据库。 :)

正如我之前所说的那样,所有的计划都很好,但最后还要运行自己的基准测试。

答案 1 :(得分:1)

我认为没有任何实际情况需要你。

当您的表格中包含更多列时,ab不是唯一的,并且您需要使用以下两个查询获得高性能时才有意义:

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的{​​{1}}和9来查找i_t_b_a的所有行。这仍然比全表扫描快得多(必须同时读取所有a=1),但速度不如使用x快。