Mysql
 sql >> Database >  >> RDS >> Mysql

Spiega il piano nelle prestazioni di MySQL usando Using temporary; Utilizzo di filesort; Utilizzo della condizione di indice

Si prega di fornire SHOW CREATE TABLE .

Il filtro principale sembra essere

            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

Probabilmente l'unico indice utile per questo è, in questo ordine:

INDEX(DSR_BOOKED_BY, dsr_booking_date)

Cose come

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

dovrebbe probabilmente essere fatto insieme. Considera qualcosa come

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

Oppure, se necessario, crea una tabella temporanea con quella sottoquery, quindi UNISCITI A SINISTRA.

(Dato che non hai qualificato ogni colonna con la tabella in cui si trova, non posso essere più specifico.)

Hai degli indici 'compositi' adatti per i vari JOINs ?

Secondo il EXPLAIN , sta eseguendo la scansione di 182 milioni di righe di dsr_table . Quindi, è probabile che il mio indice, sopra, ti aiuti (se non ne hai già uno simile.)

Esito a suggerire un indice così lungo, ma questo potrebbe aiutare:

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

Problema grave nella seconda query

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

Forse intendevi 31 giorni:

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

O forse 2 giorni:

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

Quello che hai è

        WHERE  dsr_booking_date = '2017-04-30'  -- test for one day
          AND  true  -- that's how '2017-05-30' is interpreted