Query yang melibatkan IN dan NOT IN dalam klausa WHERE nya terkenal sangat lambat sekali. Oleh karena itu, perlu optimalisasi. Berikut adalah contoh optimaliasi yang dapat dilakaukan.
Sebelum Optimalisasi
SELECT * FROM tbl_customer WHERE cstatus IN('A','B') AND ckode_depot='U10' AND ckode_customer NOT IN(SELECT ckode_customer FROM tbl_penjualan WHERE dtanggal BETWEEN '2011-12-01' AND '2011-12-31' GROUP BY ckode_customer);
Sesudah Optimalisasi
SELECT * FROM tbl_customer AS c LEFT JOIN (SELECT DISTINCT ckode_customer FROM tbl_penjualan WHERE dtanggal BETWEEN '2011-12-01' AND '2011-12-31') AS p ON c.ckode_customer=p.ckode_customer WHERE c.cstatus IN('A','B') AND c.ckode_depot = 'U10' AND p.ckode_customer IS NUll ;
Sebelum Optimalisasi
SELECT sh.cnofaktur AS cnofaktur,
sh.dtanggal AS dtanggal,
sh.ckode_customer AS ckode_customer,
tc.cnama AS cnama,
IFNULL(SUM((sd.ndebit*(1+(sh.ntax/100)))+sh.nfreight),0) nsales,
0 ndebit,
0 nreceipt,
0 ncredit
FROM tbl_sales_h sh,
(SELECT sh.cnofaktur,
IFNULL(SUM((sd.nqty*sd.nprice)-sd.ndisc),0) ndebit
FROM tbl_sales_h sh,
tbl_sales_d sd
WHERE sh.cnofaktur=sd.cnofaktur
AND sh.ckode_customer LIKE :ckode_customer
AND SUBSTR(sh.cnofaktur,4,1) = 'T'
AND sh.dtanggal BETWEEN :from_date AND :to_date
GROUP BY sh.cnofaktur) sd,
tbl_customer tc
WHERE sh.cnofaktur=sd.cnofaktur
AND sh.ckode_customer LIKE :ckode_customer
AND sh.ckode_customer = tc.ckode_customer
AND SUBSTR(sh.cnofaktur,4,1) = 'T'
AND sh.dtanggal BETWEEN :from_date AND :to_date
AND sh.cnofaktur NOT IN
( SELECT rd.cnofaktur AS cnofaktur
FROM tbl_cash_h rh,tbl_cash_d rd, tbl_customer tc
WHERE rh.cno_receipt=rd.cno_receipt
AND rh.cfrom='C'
AND rh.ckode_from = tc.ckode_customer
AND rh.ckode_from LIKE :ckode_customer
AND SUBSTR(rd.cnofaktur,4,1) = 'T' )
GROUP BY sh.cnofaktur
Hasil Explain
Lihat di alamat ini : https://gist.github.com/3753594
Sesudah Optimalisasi
SELECT sh.cnofaktur AS cnofaktur,
sh.dtanggal AS dtanggal,
sh.ckode_customer AS ckode_customer,
tc.cnama AS cnama,
IFNULL(SUM((sd.ndebit*(1+(sh.ntax/100)))+sh.nfreight),0) nsales,
0 ndebit,
0 nreceipt,
0 ncredit
FROM tbl_sales_h sh
LEFT JOIN (SELECT sh.cnofaktur,
IFNULL(SUM((sd.nqty*sd.nprice)-sd.ndisc),0) ndebit
FROM tbl_sales_h sh,
tbl_sales_d sd
WHERE sh.cnofaktur=sd.cnofaktur
AND sh.ckode_customer LIKE '%'
AND SUBSTR(sh.cnofaktur,4,1) = 'T'
AND sh.dtanggal BETWEEN '2012-01-01' AND '2012-01-31'
GROUP BY sh.cnofaktur) AS sd ON sh.cnofaktur=sd.cnofaktur
LEFT JOIN tbl_customer AS tc ON sh.ckode_customer=tc.ckode_customer
LEFT JOIN ( SELECT rd.cnofaktur AS cnofaktur
FROM tbl_cash_h rh,tbl_cash_d rd, tbl_customer tc
WHERE rh.cno_receipt=rd.cno_receipt
AND rh.cfrom='C'
AND rh.ckode_from = tc.ckode_customer
AND rh.ckode_from LIKE '%'
AND SUBSTR(rd.cnofaktur,4,1) = 'T' ) AS tch ON sh.cnofaktur=tch.cnofaktur AND tch.cnofaktur=sd.cnofaktur
WHERE sh.ckode_customer LIKE '%'
AND SUBSTR(sh.cnofaktur,4,1) = 'T'
AND sh.dtanggal BETWEEN '2012-01-01' AND '2012-01-31'
AND tch.cnofaktur IS NULL
GROUP BY sh.cnofaktur ;