Vui lòng cung cấp SHOW CREATE TABLE
.
Bộ lọc chính có vẻ là
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
Có lẽ chỉ mục hữu ích duy nhất cho điều đó, theo thứ tự sau:
INDEX(DSR_BOOKED_BY, dsr_booking_date)
Những thứ như
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) -
có lẽ nên được thực hiện cùng nhau. Xem xét một cái gì đó như
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
Hoặc, nếu cần, hãy tạo một bảng tạm thời với truy vấn con đó, sau đó THAM GIA TRÁI vào nó.
(Vì bạn chưa đủ điều kiện cho từng cột trong bảng nên tôi không thể nói cụ thể hơn.)
Bạn có chỉ mục 'tổng hợp' phù hợp cho các JOINs
khác nhau không ?
Theo EXPLAIN
, nó đang quét 182 triệu hàng của dsr_table
. Vì vậy, chỉ mục của tôi, ở trên, có khả năng hữu ích (nếu bạn chưa có chỉ mục tương tự.)
Tôi ngần ngại đề xuất một chỉ mục dài như vậy, nhưng điều này có thể hữu ích:
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
Sự cố tồi tệ trong truy vấn thứ hai
WHERE dsr_booking_date = '2017-04-30'
AND '2017-05-30'
Có lẽ ý bạn là 31 ngày:
WHERE dsr_booking_date BETWEEN '2017-04-30'
AND '2017-05-30'
Hoặc có thể 2 ngày:
WHERE dsr_booking_date IN ('2017-04-30', '2017-05-30')
Những gì bạn có là
WHERE dsr_booking_date = '2017-04-30' -- test for one day
AND true -- that's how '2017-05-30' is interpreted