Stále na tento termín zapomínám, protože se ke mně dostává velmi zřídka, ale vaše indexy každopádně nelze optimalizovat pomocí MONTH() a YEAR(), protože jsou to funkce na podkladových datech. Při použití časového rozsahu mohou. Můžete si tedy ponechat svůj měsíc/rok, jako kdyby bylo něco vytvořeno v lednu 2021 a aktualizováno v březnu 2021, ale navíc přidáním "a c.date_created>=current_date AND current_date <=c.date_updated" , můžete použít index, pokud má v sobě vytvořené datum (v tomto případě méně důležité pro datum aktualizace. Podobně pro vaši další tabulku.
Navíc, když máte levý spoj z tabulky "a" do "c" a poté použijete kde, je to skoro jako byste se pokusili vynutit připojení, ale zůstalo levé připojení kvůli OR.
Přesunul bych podmínku založenou na "c" do levého spojení a pak bych jen otestoval záznam, který tam byl nalezen, jako NULL nebo ne.
Ačkoli to není jasné (nebylo to objasněno, když jsem se ptal), MYSLÍM si, že když je vytvořen nový záznam „A“, systém může ve skutečnosti vložit datum vytvoření jak do data vytvoření, tak do data aktualizace. POKUD JE TOHLE TAK, pak se musíme pouze dotazovat/týkat se posledního aktualizovaného pole data s aktuálním měsícem/rokem činnosti. To je nyní PRIMÁRNÍ požadavek pro klauzuli where -- BEZ OHLEDU na základní podmínku OR pro tabulku "C".
Navíc, protože month() a year() nejsou sargeable (Díky Ollie), dělám předběžný dotaz, abych získal začátek aktuálního měsíce a příští měsíc, abych mohl sestavit
WHERE > beginning of this month and LESS than beginning of next month
Pokud jde o indexy, začal bych aktualizovat na
loan_applications_tbl ( date_created, date_updated, loan_status, current_loan, ippis )
topup_or_reapplication_tbl ( ippis, status, current_loan, date_created, date_updated )
Poslední dotaz k vyzkoušení.
SELECT
a.id,
a.user_unique_id,
a.loan_location,
a.ippis,
a.tel_no,
a.organisation,
a.branch,
a.loan_agree,
a.loan_type,
a.appr,
a.sold,
a.loan_status,
a.top_up,
a.current_loan,
a.date_created,
a.date_updated,
c.loan_id,
c.user_unique_id tu_user_unique_id,
c.ippis tu_ippis,
c.top_up_approved,
c.loan_type tu_loan_type,
c.dse,
c.status,
c.current_loan tu_current_loan,
c.record_category,
c.date_created tu_date_created,
c.date_updated tu_date_updated
FROM
-- this creates inline mySQL variables I can use for the WHERE condition
-- by doing comma after with no explicit join, it is a single row
-- and thus no Cartesian result, just @variables available now
( select
-- first truncating any TIME portion by casting to DATE()
@myToday := date(curdate()),
@howFarBack := date_sub( @myToday, interval 6 month ),
-- now subtract day of month -1 to get first of THIS month
@beginOfMonth := date_sub( @myToday, interval dayOfMonth( @myToday ) -1 day ),
-- and now, add 1 month for beginning of next
@beginNextMonth := date_add( @beginOfMonth, interval 1 month ) ) SqlVars,
loan_applications_tbl a
LEFT JOIN topup_or_reapplication_tbl c
ON a.ippis = c.ippis
AND c.current_loan='1'
AND c.status IN ('pending', 'corrected', 'Rejected',
'Processing', 'Captured', 'Reviewed', 'top up')
AND
(
(@beginOfMonth <= c.date_created
AND c.date_created < @beginNextMonth)
OR
(@beginOfMonth <= a.date_updated
AND a.date_updated < @beginNextMonth )
)
WHERE
-- forces only activity for the single month in question
-- since the "a" table knows of any "updates" to the "C",
-- its updated basis will keep overall restriction to any accounts
-- updated within this month in question only
-- testing specifically for created OR updated within the
-- current month in question
a.date_created >= @howFarBack
AND
(
(@beginOfMonth <= a.date_created
AND a.date_created < @beginNextMonth)
OR
(@beginOfMonth <= a.date_updated
AND a.date_updated < @beginNextMonth )
)
-- and NOW we can easily apply the OR without requiring
-- to run against the ENTIRE set of BOTH tables.
AND (
c.ippis IS NOT NULL
OR
( a.loan_status IN ( 'pending', 'corrected', 'Rejected', 'Processing',
'Captured', 'Reviewed', 'top up')
AND (
a.current_loan = '1'
OR ( a.current_loan = '0'
AND a.loan_status IN ('Approved', 'Closed')
)
)
)
)
ZÁVĚREČNÉ KOMENTÁŘE K DOTAZU
Upravil jsem dotaz a také primární index na první tabulce tak, aby ZAHRNULY (první pozice) datum vytvoření záznamu. Také jsem přidal další proměnnou @howFarBack, která má být maximální dobou návratu, kterou lze u půjčky zvážit. Před 6 měsíci jsem se vrátil. Potřebovali byste někdy pro půjčku zvážit daný účet starší než 6 měsíců? Nebo je záznam „a“ účtu něčím, co by se mohlo vrátit o 10 let zpět a chcete to zahrnout? Můj dojem je, že je to nové datum přidání ŽÁDOSTI O ÚVĚR. Pokud ano, povolení vrátit se o 6 měsíců zpět, než bude schváleno, finalizováno, zrušeno, by stále bránilo procházet historicky tolik měsíců dat.
V klauzuli WHERE jsem přidal explicitní přidání pro CREATED_DATE>=@howFarBack. Nikdy by nebylo možné vytvořit podřízený záznam, natož aktualizovat kdykoli před původním datem přidání. Tím se kvalifikuje pouze aktivita za aktuální měsíc NEBO VPŘED.
Příklad:Vytvořte půjčku 28. dubna. Když tedy spustíme dotaz, začátek měsíce je 1. duben, ale MÉNĚ než 1. květen (to umožňuje zahrnutí 30. dubna ve 23:59:59)
Nyní se dostáváme do května a změna půjčky je provedena 4. května. Jsme v novém měsíci a @howFarBack stále umožňuje starším aplikacím až do prosince 2020, aby se MOŽNÁ kvalifikovaly v porovnání s celou tabulkou aplikací, které by mohly sahat až do roku 2005, jak víme. Vždy zůstáváte s nejaktuálnějšími daty a @howFarBack můžete dostatečně snadno změnit jako maximální dobu návratu. To by mělo pomoci vašim potřebám výkonu.