Uveďte prosím SHOW CREATE TABLE
.
Zdá se, že hlavní filtr je
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
Pravděpodobně jediný užitečný index pro to je v tomto pořadí:
INDEX(DSR_BOOKED_BY, dsr_booking_date)
Věci jako
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) -
asi by se to mělo dělat společně. Zvažte něco jako
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
Nebo v případě potřeby vytvořte dočasnou tabulku s tímto poddotazem a poté se k ní PŘIPOJTE LEVÝM.
(Protože jste nekvalifikovali každý sloupec tabulkou, ve které se nachází, nemohu být konkrétnější.)
Máte vhodné 'složené' indexy pro různé JOINs
?
Podle EXPLAIN
, skenuje 182 milionů řádků dsr_table
. Takže můj index výše pravděpodobně pomůže (pokud podobný ještě nemáte.)
Váhám s navržením tak dlouhého indexu, ale mohlo by to pomoci:
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
Špatný problém ve druhém dotazu
WHERE dsr_booking_date = '2017-04-30'
AND '2017-05-30'
Možná jste mysleli 31 dní:
WHERE dsr_booking_date BETWEEN '2017-04-30'
AND '2017-05-30'
Nebo možná 2 dny:
WHERE dsr_booking_date IN ('2017-04-30', '2017-05-30')
To, co máte, je
WHERE dsr_booking_date = '2017-04-30' -- test for one day
AND true -- that's how '2017-05-30' is interpreted