【问题标题】:Should we include sort column, primary key on composite index (MySQL)我们是否应该在复合索引(MySQL)上包含排序列、主键
【发布时间】:2015-05-10 14:08:44
【问题描述】:

表格(简体):

+---------------------------------------------------------------------+
| id (Primary AI) |  user_id  |  status  |  type  |   data   |   ip   |
+=====================================================================+
|        1        |     3     |    0     |   abc  |   a-s-d  |    -   |
+---------------------------------------------------------------------+
|        2        |     1     |    0     |   ooo  |   z-z-z  |    -   |
+---------------------------------------------------------------------+
|        3        |     3     |    0     |   ooo  |   f-f-f  |    -   |
+---------------------------------------------------------------------+
|        4        |     2     |    0     |   abc  |   h-h-h  |    -   |
+---------------------------------------------------------------------+
|        5        |     1     |    0     |   abc  |   a-s-d  |    -   |
+---------------------------------------------------------------------+

更多信息:

ID是这个表的主键(自增)

请注意,我在新索引中使用 ID (Primary Key) 作为第三个 Seq_in_index

我已经为提到的表创建了一个综合索引

CREATE INDEX userid_type_id ON table (user_id, type, id);

此索引中的id 仅用于排序。

示例查询

SELECT id, status, data, ip 
                      FROM `table`
                      WHERE user_id=3 AND type='abc' 
                      ORDER BY id DESC;

我的问题是:

  1. 在复合索引中插入ID 是一种好的(性能)做法吗?因为它仅用于 ORDER BY

  2. ID(主键)作为索引中的第三个序列,而它是表上的第一列,可以吗

  3. 我是否根据示例查询正确选择了索引?

编辑:

我使用 InnoDB

【问题讨论】:

    标签: mysql


    【解决方案1】:

    答案取决于您使用的引擎:

    • MyISAM - 将 id 添加到索引可以而且可能会有所帮助
    • InnoDB - 主键已经是每个二级索引的一部分,因为 innodb 将行存储在按主键排序的 BTREE 中,并且索引需要主键指向实际行 - 在这种情况下,如果它是索引中的最后一个,则添加它是多余的 (但这样做不会添加两次,所以它不应该让事情变得更糟)。在某些情况下,您可能希望将其添加为非最后一个,或者您有多列主并且您以不同的顺序将一些列添加到索引中 - 它应该没有问题,innodb 会将剩余的主列附加到该索引,但可以使用之前添加的那些而不复制它们)

    所以回答:

    1. 在 InnoDB 中是不必要的,在 MyISAM 中,如果您实际使用该排序,则很好,如果您不使用它,添加它只会使该索引变大。
    2. 表定义中的列顺序和索引中的顺序是分开的东西,所以没关系
    3. 是的,该索引看起来非常好 - 但您可以使用 EXPLAIN 检查自己,有可能获得更好的性能 - “covering index”,但这会带来成本,因此除非查询很关键且性能不佳,这可能是矫枉过正。

    【讨论】:

    • 在使用 id 进行一致分页时,我没有看到 mysql 的相同行为。我正在使用模式: WHERE column = 'x' AND id > "LAST_VALUE" ORDER BY id LIMIT 10 我的解释没有使用整个查询的列索引,它仍然在使用索引后执行文件排序列来检索结果。 (在这里发布一个老问题,因为这个答案导致我遇到问题)
    • @Michael 你能粘贴/概括你的查询、表格和解释输出或将其作为问题发布吗?评论太短了。
    • 感谢您关注@jkavalik。抱歉,拖了这么久,这是一个包含完整详细信息的新问题:stackoverflow.com/questions/57223858/…
    猜你喜欢
    • 2012-05-19
    • 1970-01-01
    • 1970-01-01
    • 2021-04-29
    • 1970-01-01
    • 1970-01-01
    • 2013-03-20
    • 1970-01-01
    • 2013-01-28
    相关资源
    最近更新 更多