2012-04-04 7 views
3

Wie Sie sehen können, könnte Oracle zwei Indizes ausnutzen und die gesamte Abfrage ohne Zugriff auf die Tabelle von Rowid zu lösen?Oracle: Nutzen Sie die Verwendung von zwei Index

SELECT 'Scarti letture GAS' tipo, campo47 pdf, COUNT (1) n 
    FROM out.CONSUMI_GEE_LC_T500_00 v 
    WHERE stato = 'SC' 
    AND stato is not null 
    AND campo47 is not null 
    GROUP BY 'Scarti letture GAS', campo47; 

Ich habe einen Test gemacht, der das Feld campo47 zum STATO-Index hinzufügt. Die Leistung steigt von 1 '49' 'auf 0,6s.

Index auf stato ist nicht selektiv. Index auf campo47 (es bedeutet Feld47) ist wirklich selektiv.

enter image description here

enter image description here

enter image description here

Antwort

7

Sie sagen CAMPO47 sehr selektiv ist. Aber Sie filtern nur nach IS NOT NULL. Es ist also egal, wie viele verschiedene Werte es hat, der Optimierer wird es nicht als Einstiegspunkt verwenden.

Und wie selektiv ist das? Wie Sie anhand der Kardinalitäten im EXPLAIN-Plan sehen können, werden bei Auswahl von STATO = 'SC' 12856 Zeilen in Ihrer Tabelle gefunden. 12702 dieser Zeilen haben offensichtlich CAMPO47 mit einem Wert, so dass nur 154 Zeilen durch den Test auf Nichtigkeit herausgefiltert werden. Wenn der Optimierer den CAMPO47-Index bestimmt hätte, wie viele Zeilen hätte das zurückgegeben? Wahrscheinlich viel mehr.

Der Optimierer kann nur einen Heap-Index verwenden, um auf Zeilen in einer Tabelle zuzugreifen. (Der Mechanismus unterscheidet sich für Bitmap-Indizes, wenn sie eine Sterntransformation anwenden). Also, wenn Sie denken, dass die zusätzlichen Tabellenzugriffe eine unerträgliche Last sind, dann haben Sie eine Option: einen zusammengesetzten Index. Wenn STATO wirklich unselektiv ist (relativ wenige Zeilen), dann ist es wahrscheinlich sicher, dass Sie den vorhandenen Index durch einen anderen ersetzen (STATO, CAMPO47).


ein alter Trick ist, die Datenbank für nudging in einen Index für den Zugriff IS NOT NULL-Operationen, und das ist ein Operand zu verwenden, die nur wahr sein kann, wo die Spalte einen Wert enthält. Zum Beispiel String-Spalt so etwas wie dies für (ich gehe davon etwas namens CAMPO47 hasen nur einen String zu sein):

AND campo47 >= chr(0) 

, dass jede Spalte übereinstimmen, die ein oder mehr ASCII-Zeichen enthält. Nicht sicher, ob es zu der "zwei Index" Optimierung führt, die Sie beschreiben, aber es ist einen Versuch wert. (Ich würde dies selbst testen, aber ich habe keinen Zugriff auf eine Oracle-Datenbank jetzt und SQL Fiddle geschleudert, als ich versuchte, auf dem Plan sehen) Erklärens

+0

Wie kann ich den Einsatz wählen/Leistung mit unterschiedlicher Art Test Index? d. h. den Index auf STATO durch (STATO, CAMPO47) ersetzen oder den Index auf STATO und Campo47 fallen lassen und sie nur durch einen Index ersetzen (STATO, CAMPO47). – Revious

+0

Ich glaube, Oracle durch den Zugriff auf alle Rowid mit stato = ‚SC‘ Grund sollte dann einen schnellen, vollständigen Index Scan des Index auf campo47 Herstellung von Rowid suchen und überhaupt ohne Zugriff auf die Tabelle direkt die resutl zurück. – Revious

+0

@APC könnten Sie mir eine E-Mail 'admin at sqlfiddle dot com' senden oder einfach hier verlinken, ein Beispiel für das Problem, das Sie mit dem Ausführungsplan auf sqlfiddle gefunden haben? Vielen Dank –

Verwandte Themen