在MySQL中这种查询的最佳索引是什么?

时间:2015-12-09 10:02:59

标签: mysql database indexing

所以这是我的表:

create table page_relation (
     relationid int primary key,
     userid int,
     pageid int,
     registryid int 
);

让我们想象一下,我想要了解用户每一页的所有注册表的数量。 以下是我将要运行的查询:

select count(*) as register_count
from page_relation
where userid = 10 
group by pageid;

我需要帮助找出加速这一查询的最佳索引是什么。

到目前为止,我尝试使用复合索引超过(userid, pageid),希望MySQL将该索引用于分组,但不幸的是,当我使用EXPLAIN时,额外的信息不包含任何“使用索引进行分组”信息,只说我使用索引,我在哪里使用。这是否意味着我的索引没有被用于排序?

理论上如果它是聚集的,这个索引不会起作用吗?我认为B-Tree,聚集和稀疏索引可以很好地完成这项工作......说实话,我期待它甚至可以作为覆盖索引,但我无法确定它是否存在。

这是我的解释声明:

# id, select_type, table, type, possible_keys, key, key_len, ref, rows,  Extra
  1, SIMPLE, page_relation, ref, idx_count, idx_count, 4, const, 60, Using where; Using index

仅用于执行此查询的最佳索引是什么?

感谢您的时间。

2 个答案:

答案 0 :(得分:0)

使用下面提到的两种方法可以满足要求:

  1. 复合索引(userid,pageid)
  2. 查询:

    select  userid,pageid,count(*) as register_count
    from page_relation
    where userid = 10 
    group by userid,pageid;
    
    1. 两个索引 - 一个在userid上,另一个在pageid上
    2. 查询:查询将保持与问题中提到的相同。

      注意:对于复合键,MySQL按声明顺序使用索引。例如,组合键(userid,pageid)必须使用字段userid进行过滤或分组,否则将忽略索引。

      第一种方法的好处是它只能引用一个索引。数字索引越少,写入效率越高。考虑到空间和时间的复杂性,我建议您1st approach进行BTREE索引。

      假设:pageid字段不是唯一的。

      注意:如果索引未在任何版本的MySQL中使用,请在group by中保留select clause个字段。

答案 1 :(得分:0)

INDEX(userid, pageid)

是唯一合理的索引。

当指示是否使用或忽略索引(在这种情况下为EXPLAIN)时,

pageid非常蹩脚。您可以尝试EXPLAIN FORMAT=JSON SELECT ...查看是否澄清了问题。

INDEX(userid), INDEX(pageid)

不太有用。它会使用一个或另一个,但不是两个。它可能会使用(userid),但这实际上并不比复合索引更好,可能更糟。

查询本身令人费解。你有多排吗?如果没有,请摆脱GROUP BY。如果是,您是否应该将pageid添加到SELECT列表?

其中大部分内容都在我的Index Cookbook中。

另一个难题......这是一个'关系'表;你是说userids和pageids之间的“多对多”映射?或者是其他东西。在很多:很多表中,通常你想要两个方向,从而需要两个方向的索引。代理id也没用,因为PRIMARY KEY (userid, pageid)是有保证的。 (见我的食谱。)

我将此升级到PRIMARY KEY,可以提高效率。

我越来越深入“if ifs”;解决我的一些问题;然后我会进一步漫步。