【问题标题】:MySQL: make a compound index of 3 fields, or make 3 separate indices?MySQL:制作 3 个字段的复合索引,还是制作 3 个单独的索引?
【发布时间】:2011-05-10 20:16:57
【问题描述】:

我有一个 MySQL 表,其中包含时间戳、类型和 user_id 等属性。
所有这些都是可搜索和/或可排序的。
是为每个索引创建一个索引,还是将这三个索引都创建一个复合索引更好,还是两者兼而有之?

【问题讨论】:

    标签: mysql indexing compound-index


    【解决方案1】:

    如果您要单独对这些字段执行搜索,您可能需要单独的索引以使您的查询运行得更快。

    如果你有这样的索引:

    mysql> create index my_idx on my_table(tstamp, user_id, type);
    

    而你查询的是:

    mysql> select * from my_table where type = 'A';
    

    那么my_idx 不会对您的查询有太大帮助,MySQL 最终会进行全表扫描来解决它。

    【讨论】:

    • ...对于select * from my_table where tstamp = @ts1等查询仍然有帮助
    • 是的,它可能有助于查询。但不会像该列上的索引only那样有用。
    • 是的,实际上它与仅在该列上的索引一样有用。由于索引更大,它可能会更慢 - 但是,如果单列上的索引有用(即高选择性),那么复合索引将同样有用 - mysql 可能会查看更大的索引,但 btree 索引是有组织的作为树,因此大小增加,再加上只需要访问树的一部分这一事实,再加上 I/O 操作以块大小发生的事实,转化为:具有相同起始列的索引同样有助于该列的条件。
    • 此外,蠕虫数据库会将索引保留在 RAM 中,因此它进一步降低了性能差异(这里假设复合索引本身是合理的)。换句话说 - 通常在引入复合索引时,我倾向于删除第一列的单列索引。
    • @Unreason,“蠕虫”数据库?
    【解决方案2】:

    Pablo 的回答是正确的,但您可能没有意识到复合索引可能是合理的。

    您可以拥有多个索引并且拥有idx1(tstamp, user_id) 并不排除您拥有indx2(tstamp, type)idx1reverse(user_id, tstamp) 等等...

    复合索引在涵盖查询中的所有条件时最有用,因此您建议的索引将最有用

    SELECT * FROM my_table WHERE tstamp = @ts1 AND user_id = @uid AND type = @type
    

    如果您想提高此类查询的性能,可以考虑添加复合索引。

    索引的缺点是它会减慢所有更新操作。然而,大多数通用应用程序执行更多的选择然后更新(无论是在事务方面,即语句的数量,特别是在受影响/检索的记录方面),同时更能容忍较慢的更新(用户主要判断速度系统不是在需要更新记录的时候,而是在需要检索记录的时候;同样是 YMMV,有些应用程序不遵守这些规则)。

    如果您有某种方法可以根据典型工作负载测试数据库性能(创建一些典型的 SQL 脚本;独立且可重复,或者在应用程序级别创建单元测试),然后您可以客观地调整您的数据库.

    编辑 还要意识到可以添加和删除索引而不影响系统的功能。因此,您可以稍后在实际使用系统期间调整索引 - 通常您会收集和分析缓慢的 SQL 查询,以寻找可以从添加索引中受益的条件。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-08-14
      • 2012-08-30
      • 2012-11-16
      • 2019-05-12
      • 2018-06-02
      • 2011-08-08
      • 2013-06-16
      相关资源
      最近更新 更多