Jediný způsob, jak si mohu myslet, jak dosáhnout takového rozdílu v rychlosti provádění, by bylo (a) mít index na field4
a (b) mají hodně prázdných datových bloků; pravděpodobně z vysoké hladiny nastavené velmi vysoko opakovaným zatížením přímou cestou.
První dotaz by stále používal index a fungoval by podle očekávání. Ale protože hodnoty null nejsou indexovány, index nelze použít ke kontrole or field4 is null
stavu, takže by se vrátilo k úplnému prohledání tabulky.
To samo o sobě by zde neměl být problém, protože úplné naskenování tabulky o 7000 řádcích by nemělo trvat dlouho. Ale protože je trvá to tak dlouho, děje se něco jiného. Úplné prohledání tabulky musí prozkoumat každý datový blok přidělený tabulce, aby se zjistilo, zda neobsahuje nějaké řádky, a čas, který to trvá, naznačuje, že je mnohem více bloků, než potřebujete, abyste podrželi 7000 řádků, a to i s inline CLOB úložištěm.
Nejjednodušší způsob, jak získat hodně prázdných datových bloků, je mít hodně dat a pak většinu z nich smazat. Ale věřím, že jste v již smazaném komentáři k předchozí otázce řekli, že výkon býval v pořádku a zhoršil se. To se může stát, pokud provedete přímé vkládání cesty , zejména pokud „obnovujete“ data jejich odstraněním a poté vložením nových dat v režimu přímé cesty. Mohli byste to udělat s vložkami, které mají příponu /*+ append */
náznak; nebo paralelně; nebo přes SQL*Loader. Pokaždé, když to uděláte, značka vysoké vody se posune, protože staré prázdné bloky nebudou znovu použity; a pokaždé, když se výkon dotazu, který kontroluje nuly, trochu sníží. Po mnoha iteracích by se to opravdu začalo sčítat.
Můžete zkontrolovat datový slovník a zjistit, kolik místa je přiděleno vaší tabulce (user_segments
atd.) a porovnejte to s velikostí dat, o kterých si myslíte, že skutečně máte. HWM můžete resetovat přebudováním tabulky, např.:
alter table mytable move;
(nejlépe v období údržby!)
Jako demo jsem spustil cyklus přímého vkládání a mazání 7000 řádků stokrát a pak jsem spustil oba vaše dotazy. První trvala 0,06 sekundy (většina z toho je režie SQL Devleoper); druhá trvala 1,260. (Také jsem běžel Gordon's, který dostal podobný čas, protože stále musí dělat FTS). S více iteracemi by byl rozdíl ještě markantnější, ale došel mi prostor... Pak jsem provedl alter table move
a znovu spusťte druhý dotaz, který pak trval 0,05 sekundy.