sql >> Databáze >  >> RDS >> Oracle

Oracle používá nebo ignoruje indexovaný sloupec v závislosti na formátu to_date(literal)

Ok - zkusím to, tohle je většinou dedukce z dostupných informací:

Proč Oracle volí jiný plán provádění?

Zdá se, že ve vašem druhém dotazu s neobvyklým formátem data optimalizátor netuší, jakou hodnotu má výsledné datum. Vidíte predikát filtru:

1 – filtr(TO_DATE('20140610 ','yyyymmdd ')<=TO_DATE(' 2014-06-10 23:59:59', 'yyyy-mm-dd hh24:mi:ss'))

Což znamená, že optimalizátor si ani není jistý, že první datum je menší než druhé! To znamená, že optimalizátor nemá ponětí o počtu vrácených řádků a použije pouze obecný plán, aniž by vzal v úvahu konkrétní statistiky. Bylo by to stejné, kdybyste měli uživatelsky definovanou funkci xyt(), která by vracela datum pro rozsah. Optimalizátor nemá žádný způsob, jak zjistit, jaká data-hodnota bude výsledkem – To znamená, že získáte obecný univerzální plán, který by měl být docela slušný pro jakékoli zadané časové období.

V prvním a třetím případě se zdá, že optimalizátor rozumí datu přímo a může odhadnout počet řádků, které jsou v časovém období, pomocí statistik. Takže zatímco druhý dotaz byl na Optimalizátor jako BETWEEN X AND 3 tento dotaz je jako BETWEEN 1 AND 3 Optimalizuje tedy plán dotazů pro předpokládaný počet vrácených řádků!

Zdá se, že podivné je, že optimalizátor dotazů má takové problémy s podivným formátem data, mohl by být podán jako chyba/žádost o vylepšení...

Ale důležitý bod:

  1. Úplné prohledání tabulky nemusí být ŠPATNÝ plán... Stejně jako použití indexu není vždy rychlejší!
  2. Náklady v plánu dotazů nijak přímo nesouvisí se skutečnou dobou provádění nebo výkonem – jedná se o interní měření pro porovnání různých plánů pro STEJNÝ DOTAZ (Nemůžete tedy porovnávat náklady na různé dotazy, jako jsou vaše dotazy 1 ,2 a 3)

V zásadě, pokud vrátíte vysoký počet řádků z tabulky, úplné prohledání tabulky bez přístupu k indexu bude v mnoha případech mnohem rychlejší, zejména při provozu na určitých oddílech! - Kontrola tabulky zpřístupní pouze oprávnění pro odpovídající časové období - tedy pouze pro příslušné datum a vrátí všechny řádky z tohoto oddílu. Je to mnohem rychlejší než dotazování indexu pro každý jednotlivý řádek a následné extrahování řádku přístupem k indexu... Zkuste profilovat dotazy – úplné prohledání tabulky na oddílu by mělo být 3krát rychlejší s mnohem menším vstupem



  1. Tabulka jako argument funkce PostgreSQL

  2. Oracle SQL Check omezení mezi 2 tabulkami

  3. Jak přidat stránkování v php

  4. Ekvivalent klauzule MySQL LIMIT pro SQL SERVER