使用 group by 聚合计数 { >100 万用户} 的 Mysql 查询性能变慢

标签 mysql sql performance query-performance

查询:

select count(*) as col_0_0_, usertb0_.ACCT_STATUS_ID as col_1_0_, usertb0_.user_type as col_2_0_ 
from user_tbl usertb0_ 
inner join 
user_org_xref userorgxre1_ 
on usertb0_.USER_ID=userorgxre1_.USER_ID 
where 
(userorgxre1_.ORGANIZATION_ID in (2)) and (usertb0_.ACCT_STATUS_ID in (1 , 11 , 13 , 15 , 2)) 
group by usertb0_.ACCT_STATUS_ID , usertb0_.user_type;

表格和索引:

user_tbl ( PK: user_id) (Index: {user_id}, {ACCT_STATUS_ID},covered index:{ ACCT_STATUS_ID,user_type})
user_org_xref (pk: user_org_id, FK: user_id) (index {organization_id},{user_id})

上面的查询需要 20 秒的时间来执行,任何人都可以帮助我提高性能

当并行点击更多时,需要超过 30 秒。

查询解释:

enter image description here

enter image description here

最佳答案

EXPLAIN 输出中的查询计划与图中的不同。 EXPLAIN 计划使用 user_tbl.cc_uid_sts_type 索引(大概是在 ACCT_STATUS_ID 上)进行范围选择,从中检索 481k 行。然后它使用 USER_ID_FK_idx 索引加入 user_org_xref。如果这不包括 organisation_id,那么添加它会加快性能。

图表计划使用 ORG_ID_FK 索引(在 user_org_xref.organisation_id 上)检索 499k 行。然后它使用主键索引连接到 user_tbl,从而将具有正确 ACCT_STATUS_ID 的组织用户过滤到 249k 行。

最终,无论您以何种方式开始查询,都将不得不处理大量数据。给定组织中有将近 50 万用户,并且有类似数量的用户具有正确的 ACCT_STATUS_ID。因此,如果您确实需要提高性能,您可能需要以某种方式进行非规范化,例如将 ACCT_STATUS_ID 复制到 user_org_xref 表,尽管这显然是您最好避免的极端解决方案。

关于使用 group by 聚合计数 { >100 万用户} 的 Mysql 查询性能变慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34327940/

相关文章:

MySQL:如何组合从另一个表多次引用的列并分配适当的别名?

mysql - 自更新 MySQL 查询以来的时间

mysql - 如何在 mysql/mariadb 中实现这一点 - 排序和排序

c - 如何有效地从 C 文件中检索数据

mysql - 简单的 MySQL 查询花费的时间太长

mysql - 如何在sql查询中应用if else

c# - 如何通过 C# 将可空整数列的空值插入 SQL 表

sql - 上一次值由负变为正

mysql - 如何像抽象java父类(super class)对象一样设计SQL表?

c++ - 当我想在本地存储来自应用程序的数据并且没有外部依赖时,我有哪些选择?