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

MySQL中这种查询的最佳索引是什么?,mysql,database,indexing,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

这是我的桌子:

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;
我需要帮助找出什么是最好的索引,以加快这一quind的查询

到目前为止,我尝试在
(userid,pageid)
上使用复合索引,希望MySQL将索引用于group by,但不幸的是,当我使用EXPLAIN时,额外的信息不包含任何“using index for group by”信息,只说我正在使用索引,我正在使用where。这是否意味着我的索引不用于排序

从理论上讲,如果这个索引是聚集的,它不会工作吗?我在想一个B-树,聚集和稀疏索引会很好地完成这项工作。。。老实说,我甚至希望它是一个覆盖指数,但我真的不知道它是不是

以下是我的解释:

# 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
仅用于执行此查询的最佳索引是什么


感谢您抽出时间。

使用以下两种方法中的任何一种都可以满足要求:

  • 复合索引覆盖(userid,pageid)
  • 查询:

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

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

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

    假设:
    pageid
    字段不唯一


    注意:如果在任何版本的MySQL中都没有使用索引,请在
    select子句中保留
    groupby
    字段

    可使用以下两种方法中的任何一种来满足要求:

    INDEX(userid, pageid)
    
  • 复合索引覆盖(userid,pageid)
  • 查询:

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

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

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

    假设:
    pageid
    字段不唯一

    注意:如果在任何版本的MySQL中都没有使用索引,请在
    select子句中保留
    groupby
    字段

    INDEX(userid, pageid)
    
    是唯一要添加的rational索引

    EXPLAIN
    在指示索引(
    pageid
    在本例中)是被使用还是被忽略时是相当蹩脚的。您可以尝试
    EXPLAIN FORMAT=JSON SELECT…
    ,看看这是否澄清了问题

    INDEX(userid), INDEX(pageid)
    
    没有那么有用。它可以使用其中一个,但不能同时使用两个。它可能会使用(userid),但这本质上并不比复合索引更好,甚至更糟

    这个问题本身令人费解。你有多行吗?如果没有,请通过
    删除
    组。如果是这样,您是否应该将
    pageid
    添加到
    SELECT
    列表中

    这其中的大部分,我都在我的书里

    另一个谜题。。。这是一个“关系”表;你的意思是用户ID和页面ID之间的“多对多”映射吗?或者别的什么。在many:many表中,通常需要双向执行,因此索引必须双向执行。另外,代理
    id
    也没有用,因为
    主键(userid,pageid)
    是有保证的。(看我的食谱。)

    我将其升级到
    主键
    ,可以提高效率

    我太沉迷于“如果”了;回答我的一些问题;然后我会继续闲逛

    是唯一要添加的rational索引

    EXPLAIN
    在指示索引(
    pageid
    在本例中)是被使用还是被忽略时是相当蹩脚的。您可以尝试
    EXPLAIN FORMAT=JSON SELECT…
    ,看看这是否澄清了问题

    INDEX(userid), INDEX(pageid)
    
    没有那么有用。它可以使用其中一个,但不能同时使用两个。它可能会使用(userid),但这本质上并不比复合索引更好,甚至更糟

    这个问题本身令人费解。你有多行吗?如果没有,请通过
    删除
    组。如果是这样,您是否应该将
    pageid
    添加到
    SELECT
    列表中

    这其中的大部分,我都在我的书里

    另一个谜题。。。这是一个“关系”表;你的意思是用户ID和页面ID之间的“多对多”映射吗?或者别的什么。在many:many表中,通常需要双向执行,因此索引必须双向执行。另外,代理
    id
    也没有用,因为
    主键(userid,pageid)
    是有保证的。(看我的食谱。)

    我将其升级到
    主键
    ,可以提高效率


    我太沉迷于“如果”了;回答我的一些问题;然后我将继续漫谈。

    非常有趣,我也在某个地方面对它,等待核心DBA的回答!顺便说一句,一个表只能有一个聚集索引,而您的表聚集索引被主键占用。您也可以尝试强制索引!如果删除主键索引会怎么样?是的,索引的强度取决于它的基数。PK的基数为1。你做得再好不过了@Hytool checkout此索引
    (userid,pageid)
    是一个覆盖索引,如