sql >> Database >  >> RDS >> Oracle

Oracle gebruikt of negeert de geïndexeerde kolom, afhankelijk van het formaat van to_date (letterlijk)

Ok - ik zal het proberen, dit is meestal aftrek van de beschikbare informatie:

Waarom kiest Oracle voor een ander uitvoeringsplan?

Het lijkt erop dat in uw tweede zoekopdracht met het ongebruikelijke datumformaat, de optimizer geen idee heeft wat de waarde van de resulterende datum is. U ziet het filterpredicaat:

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

Wat betekent dat de optimizer er niet eens zeker van is dat de eerste date kleiner is dan de tweede! Dat betekent dat de optimizer geen idee heeft van het aantal geretourneerde rijen en gewoon een generiek plan zal gebruiken zonder rekening te houden met specifieke statistieken. Het zou hetzelfde zijn als u een door de gebruiker gedefinieerde functie xyt() had die een datum voor het bereik zou retourneren. De optimizer kan niet weten welke datumwaarde het resultaat zal zijn. Dit betekent dat u een algemeen plan voor alle doeleinden krijgt, dat redelijk goed zou moeten zijn voor elk gespecificeerd datumbereik.

In het eerste en derde geval lijkt de optimizer de datum direct te begrijpen en kan het aantal rijen in het datumbereik raden met behulp van statistieken. Dus terwijl de tweede Query naar de Optimizer was, zoals BETWEEN X AND 3 deze zoekopdracht is als BETWEEN 1 AND 3 Dus optimaliseert hij het zoekplan voor het voorspelde aantal geretourneerde rijen!

Het vreemde lijkt te zijn, dat de query-optimizer zulke problemen heeft met een vreemde datumnotatie, kan worden ingediend als een bug/verzoek voor verbetering...

Maar een belangrijk punt:

  1. Een volledige tabelscan hoeft geen SLECHT plan te zijn... Evenals het gebruik van een index is niet altijd sneller!
  2. De kosten in het queryplan zijn op geen enkele manier rechtstreeks gerelateerd aan de werkelijke uitvoeringstijd of prestaties - het is een interne meting om verschillende plannen voor DEZELFDE QUERY te vergelijken (u kunt dus de kosten van verschillende query's zoals uw query's niet vergelijken 1 ,2 en 3)

Als u een groot aantal rijen uit een tabel retourneert, zal een volledige tabelscan zonder indextoegang in veel gevallen veel sneller zijn, vooral wanneer u op bepaalde partities werkt! - De tabelscan heeft alleen toegang tot de pertition voor het overeenkomende datumbereik - dus alleen voor de betreffende datum en retourneert alle rijen van deze partitie. Dit is veel sneller dan het opvragen van de index voor elke afzonderlijke rij en vervolgens het extraheren van de rij door indextoegang... Probeer de zoekopdrachten te profileren - de volledige tabelscan op partitie zou 3 keer zo snel moeten zijn met veel minder IO



  1. Ondersteunt BigQuery het uitvoeren van een directe opdracht om dynamische query's uit te voeren?

  2. Hoe een bij te werken record met JSON-kolom in PostgreSQL in te voegen met JOOQ?

  3. MySQL-volgorde op duplicaten bovenaan

  4. Sysbench gebruiken om testgegevens te genereren voor Sharded Table in MySQL