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