对于Mysql按限制排序查询,按主键排序时是否需要复合索引?
如果我正在运行MySQL ORDER BY LIMIT查询,其中WHERE子句在一列上进行过滤,ORDER BY子句在主键列上进行过滤: a) 我可以只对我正在做WHERE的列使用一个索引吗?这里的例子是索引(团队id) b) 还是最好在两个上都建立索引(WHERE列、ORDER BY列)?这里的示例是索引(团队id、成员id) 我有一种预感,数据库将自然地按主键列排序,因此我认为我可以使用a)并且只需要一个索引。有人能确认一下吗 示例数据库对于Mysql按限制排序查询,按主键排序时是否需要复合索引?,mysql,indexing,Mysql,Indexing,如果我正在运行MySQL ORDER BY LIMIT查询,其中WHERE子句在一列上进行过滤,ORDER BY子句在主键列上进行过滤: a) 我可以只对我正在做WHERE的列使用一个索引吗?这里的例子是索引(团队id) b) 还是最好在两个上都建立索引(WHERE列、ORDER BY列)?这里的示例是索引(团队id、成员id) 我有一种预感,数据库将自然地按主键列排序,因此我认为我可以使用a)并且只需要一个索引。有人能确认一下吗 示例数据库 CREATE TABLE `team_member`
CREATE TABLE `team_member` (
`member_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`team_id` int(11) unsigned NOT NULL,
`name` varchar(200) NOT NULL,
...
(several more columns of info)
...
PRIMARY KEY (`member_id`),
KEY `IDX_TeamMember_TeamId` (`team_id`)
) ...
示例查询
select *
from `member`
where `team_id` = 11111
order by `member_id`
limit 0,10
MySQL服务器版本5.6.10
非常大的表,规模是一个大问题优化器倾向于在查看
ORDER BY
之前完全处理WHERE
子句
除非整个WHERE
、GROUP BY
和ORDER BY
由单个索引处理,否则无法有效处理限额
优化器有时会跳过WHERE
子句,并根据orderby
查找索引。这是你的建议。但它必须扫描大量带有“错误”团队id的行。它可能需要扫描整个表才能找到10行。因此,这可能是一个“糟糕”的计划
您可以人工更改主键
,以优化某些重要查询。例如:
PRIMARY KEY(team_id, member_id),
UNIQUE(member_id)
UNIQUE
同时保留当前的索引和唯一性检查。PK必须是“唯一的”;通过在其中包含成员\u id
,可以保证它是唯一的。现在,数据首先由团队id
排序(因此将有效地处理其中的,然后由成员id
排序,以便处理排序依据
。而且,由于它已通过这两个步骤,因此您的选择
将接触不超过10行(限制
)
有了那个PK和那个查询,它不仅能够在10行之后停止,而且这10行很可能在一个磁盘块中(或者可能是一小部分“连续”块)。你再好不过了
是的,InnoDB按主键对数据进行排序
为什么目标是只有一个索引?多个索引不是一件坏事。这对插入的来说是一个很小的负担,但对一些选择的来说可能是一个很大的好处
这张桌子有多大?我推荐的即使是十亿行的桌子也不错
选择性(基数)复合索引的第一列的排序是不相关的。列组合的选择性可能会起作用。但是,您的示例不太可能受到影响。取决于条件,其中`team\u id`=11111
选择性。如果它过滤的总行数小于~5-7%,则索引按(team\u id,member\u id)
必须提高性能,否则不需要复合索引。InnoDB会将PK隐式添加到索引末尾。