sql >> Database >  >> RDS >> Mysql

Leg plan uit in mysql-prestaties met behulp van Tijdelijk gebruiken; Filesort gebruiken; Indexvoorwaarde gebruiken

Geef a.u.b. SHOW CREATE TABLE .

Het hoofdfilter lijkt te zijn

            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

Waarschijnlijk de enige bruikbare index daarvoor is, in deze volgorde:

INDEX(DSR_BOOKED_BY, dsr_booking_date)

Dingen zoals

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

moet waarschijnlijk samen worden gedaan. Overweeg iets als

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

Of, indien nodig, bouw een tijdelijke tabel met die subquery en LEFT JOIN ernaartoe.

(Aangezien je niet elke kolom hebt gekwalificeerd met de tabel waarin deze zich bevindt, kan ik niet specifieker zijn.)

Heeft u geschikte 'samengestelde' indexen voor de verschillende JOINs ?

Volgens de EXPLAIN , het scant 182 miljoen rijen dsr_table . Dus mijn index hierboven zal waarschijnlijk helpen (als je nog geen vergelijkbare hebt.)

Ik aarzel om zo'n lange index voor te stellen, maar dit kan helpen:

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

Slecht probleem in tweede zoekopdracht

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

Misschien bedoelde je 31 dagen:

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

Of misschien 2 dagen:

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

Wat je hebt is

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



  1. MySQL slaat ongerichte grafiekranden efficiënt op

  2. Het resetten van AUTO_INCREMENT duurt lang in MySQL

  3. Best practices voor noodherstel van Microsoft SQL Server

  4. Minimale afstand en groeperen op