Warum verwendet Oracle hier den Index?

7
Name     Null     Type      
-------- -------- --------- 
ID       NOT NULL NUMBER(4) 
GROUP_ID          NUMBER(4) 
TEXT              CLOB      

Es gibt einen btree Index auf group_id. Hier ist, wie viele Zeilen jede group_idhat und der entsprechende Prozentsatz:

GROUP_ID               COUNT                  PCT                    
---------------------- ---------------------- ---------------------- 
1                      1                      1                      
2                      2                      1                      
3                      4                      3                      
4                      8                      6                      
5                      16                     12                     
6                      32                     24                     
7                      64                     47                     
8                      9                      7                      

Ich habe das gemacht

EXEC DBMS_STATS.GATHER_SCHEMA_STATS(ownname=>'TEST', cascade=>true);

Was, wenn ich es richtig verstehe, Statistiken für den Optimierer sammelt.

Ich erinnere mich, dass Oracle den Index nicht verwendet und stattdessen einen vollständigen Tabellenscan durchführt, wenn mehr als 5% aller Zeilen abgerufen werden. Als ich diese Abfrage ausführte, wurde jedoch erst mit group_id7 Jahren ein FTS ausgeführt , das 47% aller Zeilen enthält.

Soll das so sein?

NullUserException
quelle
2
Können Sie uns die Anfrage geben?
Leigh Riffel
@LeighSELECT * FROM my_table WHERE group_id = X
NullUserException

Antworten:

3

Ich erinnere mich, dass Oracle den Index nicht verwendet und stattdessen einen vollständigen Tabellenscan durchführt, wenn mehr als 5% aller Zeilen abgerufen werden.

Dies ist eine "Faustregel" und sollte nicht als Vorhersage angesehen werden. Der Oracle CBO wählt einen Ausführungsplan basierend auf den geschätzten "Kosten" der Optionen. Die geschätzten Kosten hängen von verschiedenen Parametern ab, und die Komplexität steigt mit jeder Oracle-Version.

Sie können Hinweise verwenden und explain planeine detailliertere Vorstellung von den relativen Kosten zweier Pläne erhalten. Dies sollte jedoch in einer einzigen Abfrage erfolgen, da nicht garantiert wird, dass die „Kosten“ ein absolutes Maß außerhalb eines einzelnen Plans sind:

select /*+ FULL(foo) */ * from foo where group_id=10
union all
select /*+ INDEX(i_foo) */ * from foo where group_id=10;

Beispiel Plan mit relativen Kosten erklären

Soll das so sein?

Kurzum: Ja.

Sofern Sie kein bestimmtes Leistungsproblem festgestellt haben, sollten Sie dem CBO vertrauen, dass er den richtigen Pfad auswählt (und beispielsweise keine Hinweise verwenden, außer zum Testen und Experimentieren wie oben). Wenn Sie ein Problem identifiziert haben, besteht der nächste Schritt darin, zu untersuchen, ob der CBO falsche Annahmen trifft und wie er bessere Informationen erhalten kann, anstatt anzunehmen, dass es defekt ist, und / oder zu versuchen, es zu umgehen.

Jack sagt, versuchen Sie es mit topanswers.xyz
quelle
4

Oracle verfolgt auch die Anzahl der Blöcke, die mithilfe der Indexwerte abgerufen werden. Möglicherweise werden Ihre Daten von group_id geclustert. In diesem Fall kann es sinnvoll sein, den Index zu verwenden, wenn mehr als 5% der Zeilen abgerufen werden. Wenn die Daten für die Werte 5 und 6 ausreichend geclustert sind, kann die Verwendung des Index in etwa der vollständigen Tabellensuche einiger Blöcke entsprechen.

Die relevante Berechnung umfasst die Anzahl der abzurufenden Indexblöcke, die Anzahl der abzurufenden Datenblöcke und die für den Zugriff auf die Daten erforderliche CPU. Es gibt Optimierungsparameter, die die relativen Kosten für das Abrufen des Index gegenüber den Datenblöcken anpassen. Dies kann den verwendeten Plan ändern.

BillThor
quelle