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