sql >> Databasteknik >  >> RDS >> Mysql

Förklara plan i mysql-prestanda med hjälp av att använda temporär; Använder filesort; Använder indexvillkor

Ange SHOW CREATE TABLE .

Huvudfiltret verkar vara

            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

Förmodligen är det enda användbara indexet för det, i denna ordning:

INDEX(DSR_BOOKED_BY, dsr_booking_date)

Saker som

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

borde nog göras tillsammans. Tänk på något liknande

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

Eller, om det behövs, bygg en temporär tabell med den underfrågan och LEFT JOIN till den.

(Eftersom du inte har kvalificerat varje kolumn med tabellen den finns i kan jag inte vara mer specifik.)

Har du lämpliga 'sammansatta' index för de olika JOINs ?

Enligt EXPLAIN , den skannar 182 miljoner rader av dsr_table . Så mitt index ovan kommer sannolikt att hjälpa (om du inte redan har ett liknande.)

Jag tvekar att föreslå ett så långt index, men det här kan hjälpa:

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

Dåligt problem i den andra frågan

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

Du kanske menade 31 dagar:

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

Eller kanske 2 dagar:

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

Vad du har är

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



  1. docker mysql på annan port

  2. Vad betyder ett (+)-tecken i en Oracle SQL WHERE-sats?

  3. Så här grupperar du efter månad i PostgreSQL

  4. MySql:Räkna hur många gånger orden förekommer i en kolumn