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

时间:2018-12-18 08:19:39

标签: mysql query-optimization

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

declare @JOBS table(JOB_ID int, DateOpen varchar(10), DateFinish varchar(10), DateClose varchar(10), Location varchar(5))
insert into @JOBS values
(   100, '16-Dec-18', '18-Dec-18', '19-Dec-18', 'A'),
(   101, '16-Dec-18', '18-Dec-18', '19-Dec-18', 'A'),
(   102, '17-Dec-18', '19-Dec-18', '20-Dec-18', 'C'),
(   103, '10-Dec-18', '11-Dec-18', '16-Dec-18', 'D'),
(   104, '17-Dec-18', '19-Dec-18', '18-Dec-18', 'E')

;with allDates as (
select convert(date, DateOpen) as [Date], Location from @JOBS
union
select convert(date, DateFinish), Location from @JOBS
union
select convert(date, DateClose), Location from @JOBS
),
aggregated as (
    select [Date], Location
    from allDates
    group by [Date], Location
)
select
    a.Date
    , (select count(*) from @JOBS where a.[Date] = DateOpen and a.Location = Location) [Open]
    , (select count(*) from @JOBS where a.[Date] = DateFinish and a.Location = Location) Finished
    , (select count(*) from @JOBS where a.[Date] = DateClose and a.Location = Location) Closed
    , Location
from aggregated a
where a.Date between '20181216' and '20181217'

enter image description here

2 个答案:

答案 0 :(得分:2)

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

要启动索引,请查看WHERE子句中的元素。

这意味着应该有一个

  • audit_maincertification_id开头;
  • farmer_detailsmill_idadministrative_division_id(任何顺序)开头;和
  • addressvillage_id开头

接下来查看它们所连接的表是什么,它不是主键,请附加以下内容:

  • audit_main具有id,因为它被假定为PK,所以不需要添加。
  • farmer_details具有farmer_id(假定为PK)
  • address具有id,假定为PK,
  • farmer具有address_iduser_id(假定为PK)

最后看一下结果集。在这种情况下,只能附加audit_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 ...查询以查看所有这些索引是否正确使用。

参考文献:

答案 1 :(得分:0)

我将建议这些索引:

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。)