我们是否应该包括排序列,复合索引的主键(MySQL)

Vla*_*mir 2 mysql

表格(简体):

+---------------------------------------------------------------------+
| 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  |    -   |
+---------------------------------------------------------------------+
Run Code Online (Sandbox Code Playgroud)

更多信息:

ID 是此表的主键(自动递增)

请注意,我已用作新索引ID (Primary Key)的第3个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;
Run Code Online (Sandbox Code Playgroud)

我的问题是:

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

  2. 在表的第一列时,可以使用ID(主键)作为索引中的第三序列吗?

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

编辑:

我使用InnoDB

jka*_*lik 5

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

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

所以答案:

  1. 在InnoDB中,这是没有必要的,在MyISAM中,最好使用实际排序,如果不使用它,添加它只会使索引变大。
  2. 表定义中的列顺序和索引中的顺序是分开的,所以可以
  3. 是的,该索引看起来确实不错-但是您可以使用EXPLAIN进行检查,有可能获得更好的性能-“ 覆盖索引 ”,但这要付出代价,因此,除非查询关键且性能不佳,否则它可能会过大。