如果一个表在同一个字段上有单个索引和复合索引,那会好吗?

时间:2014-09-17 09:21:41

标签: mysql

CREATE TABLE test (
id INT NOT NULL,
last_name CHAR(30) NOT NULL,
first_name CHAR(30) NOT NULL,
PRIMARY KEY (id),
KEY `first_name` (first_name),
KEY `last_name` (last_name),
KEY `last_first` (last_name,first_name)
);

如果我有类似的查询,如果一个表在同一个字段上有单个索引和复合索引,那么它是否合适?

SELECT * FROM test WHERE first_name = 'A';
SELECT * FROM test WHERE last_name= 'A';
SELECT * FROM test WHERE last_name= 'A' AND first_name = 'A';

2 个答案:

答案 0 :(得分:0)

tl;博士答案:测试一下。答案很大程度上取决于您的数据和查询,因此我们无法给出适用于所有方案的明确答案。只要您还没有对其进行测试,就不要使用额外的复合索引。它闻起来像过早的优化。

复合索引---与只有单行索引相比--- 可以加快速度。您的上一个查询可以加速。首先,让我更深入地了解数据库的内部工作原理。

在查询处理中使用复合索引

复合索引允许为第三个查询执行单个索引扫描,以快速查找所有匹配的元组。即,DBMS只是询问索引"给我所有与两个谓词匹配的元组"。复合索引能够快速确定。

相反,如果您只有非复合索引,则不能进行此类扫描。相反,您的RDBMS将有两个选择来回答您的查询:

  1. 执行所谓的索引交集:在两个索引中查找匹配的元组,然后计算交集
  2. 仅使用其中一个索引并使用第二个谓词来过滤输出
  3. 我不确定MySQL会执行哪些策略。检查生成的计划以确定。

    加速了吗?

    如上所述,如果你有复合索引,你的RDBMS有三种处理第三个查询的可能性:

    1. 复合索引上的单个索引扫描
    2. 单行索引的索引交集
    3. 使用第二个谓词
    4. 使用一个索引和过滤元组

      现在,为了回答一个复合索引是否可以加快速度,我们必须确定哪种方式最快。简答:这取决于数据是的,复合索引的索引扫描很可能是最快的。但问题是它的速度有多快?因为额外的索引很昂贵,所以只有非常明显的加速才能证明额外的复合索引。

      尤其是谓词的选择性决定了复合索引是否值得。例如,考虑所有元组的90%满足last_name= 'A'(即,该谓词的选择性较低)。那么,复合指数将是非常多余的。简单地使用方式(3),即在不使用上一个查询中的索引的情况下对谓词进行过滤将与复合索引扫描同样快。第二种解决方案是最慢的,因为交叉点结果非常大。

      但现在考虑只有0.00001%的元组满足谓词。然后,(1)将比(3)具有巨大的好处,因为它只选择匹配的元组,而(3)选择了大量的元组,然后将大部分元组过滤掉(因为它们与谓词不匹配)。 (2)在这种情况下将是第二快的解决方案(因为交叉点大小非常小)但它不会像复合扫描那样快,因为建立交叉点总是有点昂贵(交叉可以通过使用例如,哈希加入。

      总之,复合索引的加速比有多大取决于您使用的数据和谓词。所以,你必须测试它。我们无法在这里给出确切的答案。

      这还取决于优化器的聪明程度。因此,当您更新MySQL时,它可能会更改,因为优化程序可能已更改,现在选择更好(或更糟)的策略来处理查询。

      额外的综合指数有哪些缺点?

      额外的索引需要两件事:

      1. 空间,当然。
      2. 更新时间:索引必须保持最新,因此更改索引列的插入,删除和更新会变慢。如果您有大量更新,则附加索引甚至可能会降低整体性能。
      3. 何时应使用其他复合索引?

        如上所示,附加索引有成本但可能会加快查询速度。以下是使用其他复合索引时的一些启发式方法:

        1. 您有许多查询真正使用这两列(对于所有其他查询,附加索引不会产生任何好处)
        2. 这些查询中的谓词具有高度选择性
        3. 你有足够的空间,即支付额外索引的空间不会伤害你
        4. 您的数据不是太动态,即您没有更新但查询更多,因此更新附加索引不会对您造成伤害。
        5. 但是,使用它的最佳答案是以下恕我直言:

          将另一个复合索引视为一种优化形式。因此,着名的规则适用:"程序优化的第一条规则:不要这样做。程序优化的第二条规则(仅限专家!):暂时不做。"

          仅在将多列查询识别为应用程序的瓶颈后才执行此优化。衡量差异。如果有一个相当大的,请保留索引,否则将其删除。

答案 1 :(得分:0)

由于名称的典型值范围很大,尤其是对于姓氏,因此使用简单索引进行过滤非常显着。复合索引所获得的改进将是最小的,可能无法衡量,甚至可能产生更差性能,因为每个I / O页面的索引数量较少(条目大小是大小的两倍)并且更新将会还要稍微缓慢,需要维护的索引越多。

只需在每列上使用单独的索引,让优化程序完成剩下的工作。

如果您有字符串证据表明存在直接归因于缺少复合索引的性能问题,那么只需考虑它并进行实验。