简体   繁体   中英

Laravel Join tables and group by sum query too slow

I am using Laravel query builder to get desired results from database. The following query if working perfectly but taking too much time to get results. Can you please help me with this?

select 
  `amz_ads_sp_campaigns`.*, 
  SUM(attributedUnitsOrdered7d) as order7d, 
  SUM(attributedUnitsOrdered30d) as order30d, 
  SUM(attributedSales7d) as sale7d, 
  SUM(attributedSales30d) as sale30d, 
  SUM(impressions) as impressions, 
  SUM(clicks) as clicks, 
  SUM(cost) as cost, 
  SUM(attributedConversions7d) as attributedConversions7d, 
  SUM(attributedConversions30d) as attributedConversions30d 
from 
  `amz_ads_sp_product_targetings` 
  inner join `amz_ads_sp_report_product_targetings` on `amz_ads_sp_product_targetings`.`campaignId` = `amz_ads_sp_report_product_targetings`.`campaignId` 
  inner join `amz_ads_sp_campaigns` on `amz_ads_sp_report_product_targetings`.`campaignId` = `amz_ads_sp_campaigns`.`campaignId` 
where 
  (
    `amz_ads_sp_product_targetings`.`user_id` = ? 
    and `amz_ads_sp_product_targetings`.`profileId` = ?
  ) 
group by 
  `amz_ads_sp_product_targetings`.`campaignId`

Result of Explain SQL


id  select_type table                   type    possible_keys   key     key_len     ref                         rows    Extra   
1   SIMPLE      amz_ads_sp_report_product_targetings    ALL campaignId  NULL        NULL        NULL                            50061   Using temporary; Using filesort
1   SIMPLE      amz_ads_sp_campaigns            ref campaignId  campaignId  8       pr-amz-ppc.amz_ads_sp_report_product_targetings.ca...   1   
1   SIMPLE      amz_ads_sp_product_targetings       ref campaignId  campaignId  8       pr-amz-ppc.amz_ads_sp_report_product_targetings.ca...   33  Using where

Your query could benefit from several indices to cover the WHERE clause as well as the join conditions:

CREATE INDEX idx1 ON amz_ads_sp_product_targetings (
    user_id, profileId, campaignId);

CREATE INDEX idx2 ON amz_ads_sp_report_product_targetings (
    campaignId);

CREATE INDEX idx3 ON amz_ads_sp_campaigns (campaignId);

The first index idx1 covers the entire WHERE clause, which might let MySQL throw away many records on the initial scan of the amz_ads_sp_product_targetings table. It also includes the campaignId column, which is needed for the first join. The second and third indices cover the join columns of each respective table. This might let MySQL do a more rapid lookup during the join process.

Note that selecting amz_ads_sp_campaigns.* is not valid unless the campaignId of that table be the primary key. Also, there isn't much else we can do speed up the query, as SUM , by its nature, requires touching every record in order to come up the result sum.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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