Oracle
 sql >> Datenbank >  >> RDS >> Oracle

Was sind die Leistungsauswirkungen der Oracle IN-Klausel ohne Joins?

Wenn die Statistiken für Ihre Tabelle korrekt sind, sollte es sehr unwahrscheinlich sein, dass der Optimierer einen Tabellenscan durchführt, anstatt den Primärschlüsselindex zu verwenden, wenn Sie nur 1000 hartcodierte Elemente im WHERE haben Klausel. Der beste Ansatz wäre, genaue Statistiken zu Ihren Objekten zu sammeln (oder festzulegen), da dies dazu führen sollte, dass automatisch gute Dinge passieren, anstatt zu versuchen, viel Gymnastik zu betreiben, um falsche Statistiken zu umgehen.

Wenn wir davon ausgehen, dass die Statistiken so ungenau sind, dass der Optimierer glauben würde, dass ein Tabellenscan effizienter wäre als die Verwendung des Primärschlüsselindex, könnten Sie möglicherweise ein DYNAMIC_SAMPLING hinzufügen Hinweis, der den Optimierer zwingen würde, genauere Statistiken zu sammeln, bevor er die Anweisung oder eine CARDINALITY optimiert Hinweis zum Überschreiben der Standardkardinalitätsschätzung des Optimierers. Keines davon würde erfordern, irgendetwas über die verfügbaren Indizes zu wissen, es würde nur erfordern, den Tabellenalias (oder den Namen, wenn es keinen Alias ​​gibt) zu kennen. DYNAMIC_SAMPLING wäre der sicherere, robustere Ansatz, aber es würde den Parsing-Schritt zeitaufwändiger machen.

Wenn Sie eine SQL-Anweisung mit einer variablen Anzahl hartcodierter Parameter in einem IN aufbauen -Klausel, werden Sie wahrscheinlich Leistungsprobleme für sich selbst schaffen, indem Sie Ihren gemeinsam genutzten Pool mit nicht gemeinsam nutzbarem SQL überfluten und die Datenbank zwingen, viel Zeit damit zu verbringen, jede Variante separat zu analysieren. Es wäre viel effizienter, wenn Sie eine einzige gemeinsam nutzbare SQL-Anweisung erstellen würden, die einmal analysiert werden könnte. Je nachdem, wo Ihr IN ist Klauselwerte kommen, das könnte etwa so aussehen

SELECT *
  FROM table_name
 WHERE primary_key IN (SELECT primary_key
                         FROM global_temporary_table);

oder

SELECT *
  FROM table_name
 WHERE primary_key IN (SELECT primary_key
                         FROM TABLE( nested_table ));

oder

SELECT *
  FROM table_name
 WHERE primary_key IN (SELECT primary_key
                         FROM some_other_source);

Wenn Sie sich auf eine einzige gemeinsam nutzbare SQL-Anweisung beschränkt haben, dann haben Sie zusätzlich zur Vermeidung der Kosten für das ständige erneute Parsen der Anweisung eine Reihe von Optionen, um einen bestimmten Plan zu erzwingen, der keine Änderung der SQL-Anweisung beinhaltet. Verschiedene Versionen von Oracle haben unterschiedliche Optionen für Planstabilität – es gibt gespeicherte Umrisse , SQL-Planverwaltung und SQL-Profile unter anderen Technologien, abhängig von Ihrer Version. Sie können diese verwenden, um bestimmte Pläne für bestimmte SQL-Anweisungen zu erzwingen. Wenn Sie jedoch ständig neue SQL-Anweisungen generieren, die neu geparst werden müssen, wird es sehr schwierig, diese Technologien zu verwenden.