Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Erklären Sie den Plan in der MySQL-Leistung mit Using Temporary; Verwenden von filesort; Indexbedingung verwenden

Bitte geben Sie SHOW CREATE TABLE an .

Der Hauptfilter scheint

zu sein
            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

Wahrscheinlich ist der einzige nützliche Index dafür in dieser Reihenfolge:

INDEX(DSR_BOOKED_BY, dsr_booking_date)

Dinge wie

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

sollte wohl zusammen gemacht werden. Betrachten Sie etwas wie

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

Oder erstellen Sie bei Bedarf eine temporäre Tabelle mit dieser Unterabfrage und führen Sie dann einen LEFT JOIN zu ihr.

(Da Sie nicht jede Spalte mit der Tabelle qualifiziert haben, in der sie sich befindet, kann ich nicht genauer sein.)

Haben Sie geeignete 'zusammengesetzte' Indizes für die verschiedenen JOINs ?

Gemäß EXPLAIN , scannt es 182 Millionen Zeilen von dsr_table . Mein obiger Index wird Ihnen also wahrscheinlich helfen (falls Sie noch keinen ähnlichen haben.)

Ich zögere, einen so langen Index vorzuschlagen, aber das hier könnte helfen:

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

Schlechtes Problem in der zweiten Abfrage

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

Vielleicht meinten Sie 31 Tage:

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

Oder vielleicht 2 Tage:

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

Was Sie haben, ist

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