MySQL索引与订购

时间:2016-04-28 11:39:47

标签: mysql

我有一张包含500万行的表格。我没有在这里添加索引:

CREATE TABLE `my_table` (
    `Id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
    `Title` CHAR(200) NULL DEFAULT NULL,
    `ProjectId` INT(10) UNSIGNED NOT NULL,
    `RoleId` INT(10) UNSIGNED NOT NULL,
    PRIMARY KEY (`Id`)

)
COLLATE='latin1_swedish_ci'
ENGINE=InnoDB;

当我在SQL下运行时,需要1分钟以上。

SELECT *
FROM `my_table` t
WHERE 
    t.ProjectId IN (123, 456, 789) AND 
    t.RoleId IN (111, 222, 333)
ORDER BY Title DESC
LIMIT 25

问题是,如何正确添加表的索引。你能提供任何解决方案吗?

Explain for index "ProjectId" and "RoleId" is:
key = IndxProjectIdRoleId
ref = NULL,
rows: 32,463
Extra: Using where; Using filesort

感谢您的任何建议。

2 个答案:

答案 0 :(得分:1)

您可以<{1}}和(ProjectId, RoleId, Title) 尝试索引。他们可能没多大帮助。问题是(RoleId, ProjectId, Title)中有两个不等式。

其中一个可能比当前的执行计划更好。但是,它可能没什么帮助。

MySQL实际上对多列索引有良好的documentation。您可能想要查看它。

更复杂的查询版本可能会更好:

where

这个更长版本的查询可以利用上述任一索引,因此每个索引都应该非常快。最后,查询必须排序最多9 * 25(225)个记录,即使没有索引,这也应该非常快。

答案 1 :(得分:0)

我建议使用复合索引

INDEX my_index_name (ProjectId,RoleId )

在你的情况下..

CREATE TABLE `my_table` (
  `Id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  `Title` CHAR(200) NULL DEFAULT NULL,
  `ProjectId` INT(10) UNSIGNED NOT NULL,
  `RoleId` INT(10) UNSIGNED NOT NULL,
   PRIMARY KEY (`Id`), 
   INDEX my_index_name (ProjectId,RoleId)
  )
COLLATE='latin1_swedish_ci'
ENGINE=InnoDB;

最终检查反向是否更具选择性

 INDEX my_index_name (RoleId, ProjectId)

事实上,你的表只有几列,你也可以尝试一个完整的索引表

 INDEX my_index_name (ProjectId,RoleId, Tile, id)

并选择这种方式

SELECT Id, Title, ProjectId, RoleId
FROM `my_table` t
WHERE 
   t.ProjectId IN (123, 456, 789) AND 
   t.RoleId IN (111, 222, 333)
ORDER BY Title DESC
LIMIT 25;