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

时间:2015-05-10 14:08:44

标签: 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  |    -   |
+---------------------------------------------------------------------+

更多信息:

  

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;

我的问题是:

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

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

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

  4. 编辑:

    我使用InnoDB

1 个答案:

答案 0 :(得分:4)

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

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

答案:

  1. 在InnoDB中没有必要,在MyISAM中,如果您实际使用该排序是好的,如果您不使用它,添加它只会使该索引更大。
  2. 表定义中的列顺序和索引中的顺序是不同的东西,所以没关系
  3. 是的,该索引似乎非常好 - 但您可以使用EXPLAIN检查自己,有可能获得更好的性能 - “covering index”,但这需要付出代价,除非查询是关键和表现不佳,这可能有点过头了。