Harap berikan SHOW CREATE TABLE
.
Filter utama tampaknya
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
Mungkin satu-satunya indeks yang berguna untuk itu adalah, dalam urutan ini:
INDEX(DSR_BOOKED_BY, dsr_booking_date)
Hal-hal seperti
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) -
mungkin harus dilakukan bersama-sama. Pertimbangkan sesuatu seperti
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
Atau, jika perlu, buat tabel sementara dengan subkueri itu, lalu KIRI GABUNG ke dalamnya.
(Karena Anda belum mengkualifikasi setiap kolom dengan tabel di dalamnya, saya tidak bisa lebih spesifik.)
Apakah Anda memiliki indeks 'komposit' yang sesuai untuk berbagai JOINs
?
Menurut EXPLAIN
, ia memindai 182 juta baris dsr_table
. Jadi, indeks saya, di atas, kemungkinan akan membantu (jika Anda belum memiliki indeks serupa.)
Saya ragu untuk menyarankan indeks yang begitu panjang, tetapi ini mungkin membantu:
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
Masalah buruk di kueri kedua
WHERE dsr_booking_date = '2017-04-30'
AND '2017-05-30'
Mungkin maksud Anda 31 hari:
WHERE dsr_booking_date BETWEEN '2017-04-30'
AND '2017-05-30'
Atau mungkin 2 hari:
WHERE dsr_booking_date IN ('2017-04-30', '2017-05-30')
Apa yang Anda miliki adalah
WHERE dsr_booking_date = '2017-04-30' -- test for one day
AND true -- that's how '2017-05-30' is interpreted