Explain plan in mysql performance using Using temporary; Using filesort ; Using index condition

旧时模样 提交于 2019-12-02 07:19:52

Please provide SHOW CREATE TABLE.

The main filter seems to be

            where  dsr_booking_date BETWEEN '2017-05-01' AND '2017-06-30'
              AND  LENGTH(dsr_cnno)=9
              AND  DSR_BOOKED_BY ='F'
              AND  dsr_status<>'R'
              AND  dsr_cnno NOT LIKE 'J%'
              AND  dsr_cnno NOT LIKE '@%'
              AND  dsr_cnno NOT LIKE '576%'
              AND  dsr_cnno NOT LIKE 'I3%'
              AND  dsr_cnno NOT LIKE '7%'
              AND  dsr_cnno NOT LIKE 'N%'
              and  d.dsr_dest_pin>0

Probably the only useful index for that is, in this order:

INDEX(DSR_BOOKED_BY, dsr_booking_date)

Things like

ifnull((select max(ndsr_ins_amt)     from ndx_dsr_table where ndsr_cnno=dsr_cnno ),0)-
ifnull((select max(ndsr_serv_charge) from ndx_dsr_table where ndsr_cnno=dsr_cnno ),0) -

should probably be done together. Consider something like

ifnull(mm.max_nia), 0) -
ifnull(mm.max_nsc), 0) .
...
LEFT JOIN ( SELECT max(ndsr_ins_amt)     AS max_nia,
                   max(ndsr_serv_charge) AS max_nsc
                from ndx_dsr_table
          ) AS mm  ON ndsr_cnno=dsr_cnno

Or, if necessary, build a temp table with that subquery, then LEFT JOIN to it.

(Since you have not qualified each column with the table it is in, I can't be more specific.)

Do you have suitable 'composite' indexes for the various JOINs?

According to the EXPLAIN, it is scanning 182M rows of dsr_table. So, my index, above, is likely to help (if you don't already have a similar one.)

I hesitate to suggest such a long index, but this might help:

INDEX(DSR_BOOKED_BY, dsr_booking_date,  -- these first, in this order
      dsr_cnno, dsr_status, dsr_cnno, dsr_dist_pin,  -- in any order
      id)   -- (whatever the PK of the table is); last

Bad problem in second query

        WHERE  dsr_booking_date = '2017-04-30'
          AND  '2017-05-30'

Perhaps you meant 31 days:

        WHERE  dsr_booking_date BETWEEN '2017-04-30'
                                   AND  '2017-05-30'

Or maybe 2 days:

        WHERE  dsr_booking_date IN ('2017-04-30', '2017-05-30')

What you have is

        WHERE  dsr_booking_date = '2017-04-30'  -- test for one day
          AND  true  -- that's how '2017-05-30' is interpreted
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!