sql >> Database >  >> RDS >> Oracle

Waarom gebruikt Oracle DBMS_STATS.GATHER_TABLE_STATS?

De meeste bedrijfsdatabases, waaronder Oracle, gebruiken een op kosten gebaseerde optimalisatieprogramma om het juiste queryplan voor een bepaalde SQL-instructie te bepalen. Dit betekent dat de optimizer informatie over de gegevens gebruikt om te bepalen hoe een query moet worden uitgevoerd in plaats van te vertrouwen op regels (dit is wat de oudere, op regels gebaseerde optimizer deed).

Stel je bijvoorbeeld een tabel voor voor een eenvoudige toepassing voor het opsporen van fouten

CREATE TABLE issues (
  issue_id number primary key,
  issue_text clob,
  issue_status varchar2(10)
);

CREATE INDEX idx_issue_status
    ON issues( issue_status );

Als ik een groot bedrijf ben, heb ik misschien 1 miljoen rijen in deze tabel. Daarvan hebben er 100 een issue_status van ACTIVE, 10.000 hebben een issue_status van WACHTRIJ en 989.900 hebben de status VOLTOOID. Als ik een query op de tabel wil uitvoeren om mijn actieve problemen te vinden

SELECT *
  FROM issues
 WHERE issue_status = 'ACTIVE'

de optimizer heeft een keuze. Het kan ofwel de index gebruiken op issue_status en doe vervolgens een zoekopdracht in één rij in de tabel voor elke rij in de index die overeenkomt of het kan een tabelscan uitvoeren op de issues tafel. Welk abonnement het meest efficiënt is, hangt af van de gegevens in de tabel. Als Oracle verwacht dat de query een klein deel van de gegevens in de tabel retourneert, zou het efficiënter zijn om de index te gebruiken. Als Oracle verwacht dat de query een aanzienlijk deel van de gegevens in de tabel retourneert, zou een tabelscan efficiënter zijn.

DBMS_STATS.GATHER_TABLE_STATS is wat de statistieken verzamelt die Oracle in staat stellen deze beslissing te nemen. Het vertelt Oracle dat er ongeveer 1 miljoen rijen in de tabel zijn, dat er 3 verschillende waarden zijn voor de issue_status kolom en dat de gegevens ongelijk verdeeld zijn. Oracle weet dus een index te gebruiken voor de query om alle actieve problemen te vinden. Maar het weet ook dat wanneer je je omdraait en probeert te zoeken naar alle gesloten problemen

SELECT *
  FROM issues
 WHERE issue_status = 'CLOSED'

dat het efficiënter is om een ​​tabelscan uit te voeren.

Door statistieken te verzamelen, kunnen de queryplannen in de loop van de tijd veranderen naarmate de gegevensvolumes en gegevensdistributies veranderen. Wanneer u de issue tracker voor het eerst installeert, zult u zeer weinig VOLTOOIDE problemen hebben en meer ACTIEVE en IN DE WACHTRIJ GESTELDE problemen. Na verloop van tijd stijgt het aantal VOLTOOIDE problemen veel sneller. Naarmate u meer rijen in de tabel krijgt en de relatieve fractie van de rijen in de verschillende statussen verandert, veranderen de queryplannen zodat u in de ideale wereld altijd het meest efficiënte plan krijgt.




  1. Hoe schrijf ik een Oracle Insert-script met één veld als CLOB?

  2. Kan een gedistribueerde transactie niet starten

  3. Hoe maak ik verbinding met PostgreSQL zonder een databasenaam op te geven?

  4. maak een aangepaste functie voor datumverschil met uitzondering van weekends en feestdagen in oracle sql