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

Forklar plan i mysql ydeevne ved hjælp af Using temporary; Brug af filesort; Brug af indekstilstand

Angiv venligst SHOW CREATE TABLE .

Hovedfilteret ser ud til at være

            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

Sandsynligvis det eneste nyttige indeks til det er i denne rækkefølge:

INDEX(DSR_BOOKED_BY, dsr_booking_date)

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

skal nok laves sammen. Overvej noget som

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, hvis det er nødvendigt, opbyg en midlertidig tabel med den underforespørgsel, og LEFT JOIN til den.

(Da du ikke har kvalificeret hver kolonne med den tabel, den er i, kan jeg ikke være mere specifik.)

Har du passende 'sammensatte' indekser til de forskellige JOINs ?

I henhold til EXPLAIN , den scanner 182M rækker af dsr_table . Så mit indeks ovenfor vil sandsynligvis hjælpe (hvis du ikke allerede har et lignende).

Jeg tøver med at foreslå et så langt indeks, men dette kan måske hjælpe:

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årligt problem i anden forespørgsel

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

Måske mente du 31 dage:

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

Eller måske 2 dage:

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

Det du har er

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



  1. Bestem, om der findes en kombination af mange-til-mange poster

  2. Konverter django RawQuerySet til Queryset

  3. CAST til DECIMAL i MySQL

  4. Laravel:Få en enkelt værdi fra en MySQL-forespørgsel