繁体   English   中英

MySQL计数查询优化

[英]Mysql Count query optimization

我有以下查询要优化。

SELECT count(*) AS count FROM area 
INNER JOIN entity ON area.id = entity.id
INNER JOIN areacust ON area.id = areacust.id 
WHERE entity.deleted=0 
AND area.id > 0

在所有表上都有已删除索引,id。

现在,当我假设有20个Lac(200万个)记录时,该查询将花费大量时间才能得出结果。 它在10到20秒之间。

我如何进一步优化它。 还有没有其他技术可以计数。

id  select_type table   type    possible_keys   key key_len ref rows    Extra
1   SIMPLE  vtiger_crmentity    ref PRIMARY,entity_deleted_idx  entity_deleted_idx  4      const    729726  Using where; Using index
1   SIMPLE  area    eq_ref  PRIMARY PRIMARY 4   area.id 1   Using index
1   SIMPLE  areacust    eq_ref  PRIMARY PRIMARY 4   area.id 1   Using where; Using index

复合键的新说明

id  select_type table   type    possible_keys   key key_len ref rows    Extra
1   SIMPLE  entity  ref PRIMARY,entity_deleted_idx,comp_index   deleted_idx 4   const   928304  Using index
1   SIMPLE  area    eq_ref  PRIMARY PRIMARY 4   entity.id   1   Using index
1   SIMPLE  areacust    eq_ref  PRIMARY PRIMARY 4   entity.idid 1   Using index

根据注释,如果您想保持查询的状态-您必须为您的MySQL实例分配更多资源。 我假设您将InnoDB用于存储引擎,否则此建议无用:

增加innodb_buffer_pool变量的值。 尽你所能地。 您想要分配尽可能多的RAM。

此外,摆脱deleted列上的索引,这是没有用的。 它的基数太低,无法作为索引。

您可以(应该)使用的另一种“技术”是手动处理此计数。

创建包含您感兴趣的计数编号的表。每次更新/插入/删除实体或区域记录-手动更新计数值(增加,减少)。

这样,您要做的就是查找单个表的单个记录。 设置将自动解决此问题的触发器应该很简单。 这样,您将在运行时处理计数,而不是浪费I / O和CPU来不断遍历数据集。

您可以尝试:

SELECT count(*) AS count 
  FROM area 
  JOIN entity
    ON entity.id = area.id
   AND entity.deleted = 0 
  JOIN areacust 
    ON areacust.id = area.id 

我希望在可能的情况下在JOIN中包含条件,并在这些条件下将要加入的表保持在等号的左侧。

同样WHERE area.id > 0也很奇怪..由于其他表中的auto_increment id,大多数foreign_keys从1开始,因此它将包括所有行。 我已删除此条件。

从您的解释来看,您实际上并不希望最上面的行使用entity_deleted_idx entity (id, deleted)上使用复合索引可能会带来更多乐趣

这些是我对此查询的索引:

  • area -(id)这可能已经是PRIMARY
  • areacust (id)这可能已经是PRIMARY
  • entity -(标识,已删除)应添加和使用。

UPDATE

从表entity删除所有未使用的索引,但PRIMARY和复合索引除外。

如果那不起作用,请运行:

SELECT count(*) AS count 
  FROM area 
  JOIN entity USE INDEX (**composite_index_name**)
    ON entity.id = area.id
   AND entity.deleted = 0 
  JOIN areacust 
    ON areacust.id = area.id 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM