优化MySql查询-avg(),使内部连接花费更多时间

优化MySql查询-avg(),使内部连接花费更多时间,mysql,query-optimization,Mysql,Query Optimization,使用内部联接进行平均时需要更多时间,如果我想查询100+个村庄的平均值(),则需要花费大量时间: select avg(audit_main.score) from `audit_main` inner join `farmer_details` on `audit_main`.`id` = `farmer_details`.`audit_main_id` inner join `farmers` on `farmer_details`.`farmer_id` = `farmers`.`use

使用内部联接进行平均时需要更多时间,如果我想查询100+个村庄的平均值(),则需要花费大量时间:

select avg(audit_main.score)
from `audit_main`
inner join `farmer_details` on `audit_main`.`id` = `farmer_details`.`audit_main_id` 
inner join `farmers` on `farmer_details`.`farmer_id` = `farmers`.`user_id`  
inner join `address` on `farmers`.`address_id` = `address`.`id`  
where `audit_main`.`certification_id` = 4
     and `farmer_details`.`mill_id` = 22  
     and `farmer_details`.`administrative_division_id` = 166
     and `address`.`village_id` = 139543;

MySQL在查询中每个表使用1个索引

要开始索引,请查看
WHERE
子句中的元素

这意味着应该有一个:

  • audit_main
    certification_id
    开头
  • farmer\u详细信息
    工厂id
    行政部门id
    (任何订单)开头;及
  • 地址
    村庄id开头
接下来看看它们所连接到的表是什么,它不是primar键,请附加以下内容:

  • audit\u main
    具有
    id
    ,由于假定其为主键,因此不需要添加
  • farmer\u详细信息
    具有
    farmer\u id
    (假设为PK)
  • 地址
    具有
    id
    ,假设为主键
  • farmer
    拥有
    地址id
    用户id
    (假定主键)
最后看看结果集。在这种情况下,只能添加
audit\u main.score
,因为它是一个小长度字段

因此,假设索引不存在:

CREATE INDEX idxCertScore ON audit_main (certification_id,score);
CREATE INDEX idxMillAdminDiv ON farmer_details (mill_id, administrative_division_id);
CREATE INDEX idxAddress ON farmer ( address_id);
CREATE INDEX idxVillage ON address (village_id );
添加这些索引后,显示
EXPLAIN SELECT…
query以查看是否正确使用了所有这些索引

参考资料:


MySQL在查询中每个表使用1个索引

要开始索引,请查看
WHERE
子句中的元素

这意味着应该有一个:

  • audit_main
    certification_id
    开头
  • farmer\u详细信息
    工厂id
    行政部门id
    (任何订单)开头;及
  • 地址
    村庄id开头
接下来看看它们所连接到的表是什么,它不是primar键,请附加以下内容:

  • audit\u main
    具有
    id
    ,由于假定其为主键,因此不需要添加
  • farmer\u详细信息
    具有
    farmer\u id
    (假设为PK)
  • 地址
    具有
    id
    ,假设为主键
  • farmer
    拥有
    地址id
    用户id
    (假定主键)
最后看看结果集。在这种情况下,只能添加
audit\u main.score
,因为它是一个小长度字段

因此,假设索引不存在:

CREATE INDEX idxCertScore ON audit_main (certification_id,score);
CREATE INDEX idxMillAdminDiv ON farmer_details (mill_id, administrative_division_id);
CREATE INDEX idxAddress ON farmer ( address_id);
CREATE INDEX idxVillage ON address (village_id );
添加这些索引后,显示
EXPLAIN SELECT…
query以查看是否正确使用了所有这些索引

参考资料:


我建议使用以下索引:

audit_main: (certification_id, id)
farmer_details: (audit_main_id, farmer_id, mill_id, administrative_division_id)
farmer_details: (mill_id, administrative_division_id, audit_main_id, farmer_id)
farmers: (user_id, address_id)
farmers: (address_id, user_id)
address: (village_id, id)
这允许优化器从不同的表开始,可能会找到更好的顺序来查看它们。此外,许多人在“掩护”,这又给了他们一个动力


(查看
显示创建表将有帮助)

我建议使用以下索引:

audit_main: (certification_id, id)
farmer_details: (audit_main_id, farmer_id, mill_id, administrative_division_id)
farmer_details: (mill_id, administrative_division_id, audit_main_id, farmer_id)
farmers: (user_id, address_id)
farmers: (address_id, user_id)
address: (village_id, id)
这允许优化器从不同的表开始,可能会找到更好的顺序来查看它们。此外,许多人在“掩护”,这又给了他们一个动力


(查看
SHOW CREATE TABLE

共享表上的索引详细信息(如果有)会有所帮助。共享
EXPLAIN
语句结果。对于表详细信息显示(格式为{}文本)
show CREATE table audit_main
,对于每个表,以及
EXPLAIN SELECT…
。是否希望在一个查询中显示每个村庄的所有平均值,如
SELECT address.village_id,avg(audit_main.score)FROM…
?另一个
临界点保持不变吗?你认为它的平均值是多少?将
COUNT(*)
添加到
SELECT
以查看您的猜测是否正确。如果计数远大于预期,则它不是您认为的平均值。请在表上共享索引详细信息(如果有)。共享
EXPLAIN
语句结果。对于表详细信息显示(格式为{}文本)
show CREATE table audit_main
,对于每个表,以及
EXPLAIN SELECT…
。是否希望在一个查询中显示每个村庄的所有平均值,如
SELECT address.village_id,avg(audit_main.score)FROM…
?另一个
临界点保持不变吗?你认为它的平均值是多少?将
COUNT(*)
添加到
SELECT
以查看您的猜测是否正确。如果计数比预期的要大得多,那么它就不是你认为的平均值。不客气。产生的
EXPLAIN SELECT….
输出是什么?如果您想查询所有村庄,那么与单个查询相比,SQL可能可以快速完成这些查询。回答问题/评论通常会给你一个更好的答案。不客气。产生的
EXPLAIN SELECT….
输出是什么?如果您想查询所有村庄,那么与单个查询相比,SQL可能可以快速完成这些查询。回答问题/评论通常会给你一个更好的答案。