繁体   English   中英

Mysql 此特定查询的查询优化

[英]Mysql Query Optimization for this particular query

我有一个 mysql 查询,执行大约需要 2.6 秒。 起初它没有使用索引。 现在我向它添加了索引。 但仍然没有任何改进。 对此有任何建议:

select posummary0_.id                               as col_0_0_,
       popayment1_.status                           as col_1_0_,
       posummary0_.id                               as id1_11_,
       posummary0_.created_at                       as created_2_11_,
       posummary0_.created_by                       as created_3_11_,
       posummary0_.is_active                        as is_activ4_11_,
       posummary0_.updated_at                       as updated_5_11_,
       posummary0_.updated_by                       as updated_6_11_,
       posummary0_.uuid                             as uuid7_11_,
       posummary0_.additional_cost                  as addition8_11_,
       posummary0_.additional_cost_note             as addition9_11_,
       posummary0_.approved_at                      as approve10_11_,
       posummary0_.approved_by                      as approve11_11_,
       posummary0_.can_be_rejected                  as can_be_12_11_,
       posummary0_.close_reason                     as close_r13_11_,
       posummary0_.closed_at                        as closed_14_11_,
       posummary0_.closed_by                        as closed_15_11_,
       posummary0_.delivery_fee                     as deliver16_11_,
       posummary0_.eta_date                         as eta_dat17_11_,
       posummary0_.sku_farmer_id                    as sku_far35_11_,
       posummary0_.gr_price                         as gr_pric18_11_,
       posummary0_.invoice_date                     as invoice19_11_,
       posummary0_.is_vat                           as is_vat20_11_,
       posummary0_.payment_due_date                 as payment21_11_,
       posummary0_.payment_source                   as payment22_11_,
       posummary0_.po_discount                      as po_disc23_11_,
       posummary0_.po_number                        as po_numb24_11_,
       posummary0_.po_price                         as po_pric25_11_,
       posummary0_.po_status_id                     as po_stat36_11_,
       posummary0_.po_status_update_at              as po_stat26_11_,
       posummary0_.po_summary_payment_type_id       as po_summ37_11_,
       posummary0_.po_summary_type_id               as po_summ38_11_,
       posummary0_.po_vat_type_id                   as po_vat_39_11_,
       posummary0_.receipt_id_type                  as receipt27_11_,
       posummary0_.reject_reason                    as reject_28_11_,
       posummary0_.rejected_at                      as rejecte29_11_,
       posummary0_.rejected_by                      as rejecte30_11_,
       posummary0_.revised_at                       as revised31_11_,
       posummary0_.revised_by                       as revised32_11_,
       posummary0_.total_price                      as total_p33_11_,
       posummary0_.vat                              as vat34_11_,
       posummary0_.warehouse_id                     as warehou40_11_,
       posummary0_.warehouse_distribution_center_id as warehou41_11_,
       posummary0_.warehouse_kitchen_id             as warehou42_11_,
       posummary0_.warehouse_time_window_id         as warehou43_11_
from po_summaries posummary0_
         left outer join po_payments popayment1_ on (posummary0_.id = popayment1_.po_summary_id)
         cross join sku_farmers farmer2_
         cross join warehouses warehouse3_
         cross join po_status postatus4_
where posummary0_.sku_farmer_id = farmer2_.id
  and posummary0_.warehouse_id = warehouse3_.id
  and posummary0_.po_status_id = postatus4_.id
  and (1 is null or posummary0_.is_active = 1)
  and (null is null or posummary0_.created_at >= null)
  and (null is null or posummary0_.created_at <= null)
  and (null is null or posummary0_.eta_date >= null)
  and (null is null or posummary0_.eta_date <= null)
  and ('' is null or '' = '' or farmer2_.uuid = '')
  and ('' is null or '' = '' or warehouse3_.uuid = '')
  and ('%%' is null or '%%' = '' or postatus4_.code like '%')
  and ('%%' is null or '%%' = '' or posummary0_.po_number like '%')
  and (null is null or null = '' or posummary0_.created_by like null)
order by posummary0_.created_at desc
limit 160, 20;

id 字段已编入索引。 我还为此添加了索引:

create index test_index_2 on po_status (code);

索引前说明 output: 在此处输入图像描述

索引后变成了这样: 在此处输入图像描述

我对 mysql 非常陌生,需要建议来提高性能。

一个主题演讲:如果我删除订单,那么查询执行时间就会变得更少。

谁能建议我对此查询进行优化? 计划: 在此处输入图像描述

(我认为这是我见过的最糟糕的以编程方式生成的 SQL。它是由什么程序创建的?不过,它可能实际上可以正常工作!)

这一个综合指数可能是部分救赎:

posummary0_:  INDEX(is_active, created_at)

什么时候可能需要改变

and  (1 is null
              or  posummary0_.is_active = 1
           )

and  posummary0_.is_active = 1

OR对性能来说是致命的。这个OR来自一个惰性查询生成器。)

如果你给它提供不同的选项,你可能需要另一个索引。

清理查询后,我们可以讨论将其从里向外翻。 这将允许ORDER BYOFFSETLIMIT出现所有JOINs之前。 目前该查询正在执行 57414 4 个连接。 通过重新制定,它只需要 10 4。

反了

首先,看看这是否提供了所需的 20 个 id 并运行“快速”:

select  posummary0_.id
    posummary0_.is_active = 1
    order by  posummary0_.created_at desc
    limit  160, 20;

然后构建一个类似的查询

SELECT ...  -- mostly as above
    FROM ( the 4 lines above ) AS x
    JOIN ...   -- the rest of the SQL, but without the LIMIT

暂无
暂无

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

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