Mysql
 sql >> Base de données >  >> RDS >> Mysql

Expliquez le plan dans les performances de mysql à l'aide de l'utilisation temporaire ; Utilisation du tri de fichiers ; Utilisation de la condition d'index

Veuillez fournir SHOW CREATE TABLE .

Le filtre principal semble être

            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

Le seul index utile pour cela est probablement, dans cet ordre :

INDEX(DSR_BOOKED_BY, dsr_booking_date)

Des choses comme

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

devrait probablement être fait ensemble. Considérez quelque chose comme

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

Ou, si nécessaire, créez une table temporaire avec cette sous-requête, puis cliquez sur LEFT JOIN.

(Puisque vous n'avez pas qualifié chaque colonne avec le tableau dans lequel elle se trouve, je ne peux pas être plus précis.)

Avez-vous des index 'composites' appropriés pour les différents JOINs ?

Selon le EXPLAIN , il analyse 182 millions de lignes de dsr_table . Donc, mon index, ci-dessus, est susceptible de vous aider (si vous n'en avez pas déjà un similaire.)

J'hésite à suggérer un index aussi long, mais cela pourrait aider :

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

Problème grave dans la deuxième requête

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

Vous vouliez peut-être dire 31 jours :

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

Ou peut-être 2 jours :

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

Ce que vous avez est

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