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