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

前端 未结 1 816
悲哀的现实
悲哀的现实 2021-01-25 15:33

I read various blogs and documents online but just wanted to know how i can optimize the query. I am unable to decide if we have to rewrite the query or add indexes in order to

1条回答
  •  无人及你
    2021-01-25 16:14

    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
    

    0 讨论(0)
提交回复
热议问题