2016-08-14 4 views
0

Wir haben Index auf einer Spalte die Physikalische Eigenschaften Typ ist von UTC Datum Zeit und in einem der Code haben wir diese Spalte unter where-Klausel, wie nachstehend verwendet:Index auf UTC Datum Zeit Spalte und TO_CHAR

where 
TO_DATE(TO_CHAR(**<column>**,'MM-DD-YY HH24:MI:SS'),'MM-DD-YY HH24:MI:SS') > TO_DATE(TO_CHAR(RUN_DATE,'MM-DD-YY HH24:MI:SS'),'MM-DD-YY HH24:MI:SS') 

Unser DBA markiert diese Verwendung von TO_CHAR wird sicherstellen, dass der Index nie verwendet wird.

Können Sie mir bitte helfen, zu verstehen, ob dies richtig/falsch und Begründung dahinter steht. Danke vielmals.

+0

Warum führen Sie eine Datum-zu-String-Back-to-Date-Konvertierung überhaupt durch? 'to_date (to_char (x))'. Scheint das nicht überflüssig? Und ich sehe 2 Spalten in Ihrer 'where' Klausel referenziert werden. Sind sie beide vom gleichen Typ? Sind beide indexiert?Welchen Index würden Sie vom Optimierer erwarten (unklar ohne vollständige Abfrage). Und schließlich, was ist der tatsächliche Oracle-Datentyp Ihrer 2 Spalten? Ich weiß nicht, was Sie mit "UTC Date Time" meinen. – sstan

+0

Das habe ich auch herausgefunden. Beide haben den gleichen Datentyp, also keinen Grund TO_DATE (TO_CHAR) zu machen, aber ich habe das an vielen Stellen gesehen. Gibt es einen möglichen Grund dafür, frage ich mich. –

Antwort

0

Funktionen verhindern fast immer, dass ein Index verwendet wird. In diesem Fall scheinen Sie jedoch den Wert von zwei Spalten zu vergleichen, sodass in diesem Fall auch selten Indizes verwendet werden.

Wenn Sie wirklich einen Index für diesen Zweck wollen, könnten Sie ein paar Dinge berücksichtigen. Erstens könnten Sie eine der Spalten als eine Differenz speichern. . . Wenn beispielsweise die erste Spalte ein Erstellungsdatum und die zweite ein Ausführungsdatum ist, können Sie anstelle des Datums selbst Tage bis zur Ausführung speichern.

Eine andere Möglichkeit ist der Unterschied zu indizieren:

create index idx_t_col1_col2 
    on t(col1 - col2) 

Dann im Code können Sie schreiben:

where (col1 - col2) = 0 

oder:

where (col1 - col2) >= 0 and (col1 - col2) < 1 
0

einfach das Hinzufügen von Farbe Antwort auf Gordon (was ist die richtige Antwort und sollte so markiert werden).

Erstens kann es Ihnen helfen, zu lernen, wie man EXPLAIN PLAN benutzt. In Toad oder SQL Developer (wenn Sie eines dieser Frontends verwenden, um mit Ihrer Datenbank zu interagieren), ist es so einfach wie das Ausführen einer Abfrage - Sie klicken einfach auf eine andere Schaltfläche und Sie erhalten den EXPLAIN PLAN.

Erste Frage: Wenn Sie ein Datum innerhalb von to_date (to_char (...), ...) mit einer identischen und vollständigen Maske für beide Funktionen umbrechen, ist der Optimierer intelligent genug, um dies zu erkennen und beide Funktionen zu entfernen nur dieses Datum verwenden? Antwort: NEIN; EXPLAIN PLAN zeigt, dass das Prädikat nicht wie hier vorgeschlagen vereinfacht ist. Es zeigt auch, dass date_column > SYSDATE10 einen Index verwendet, aber wenn Sie die Datumsspalte in to_date (to_char (.....)) umbrechen, führt die Engine einen vollständigen Tabellenscan durch (es wird NICHT den Index verwenden).

Zweite Frage: Könnte die Ungleichung dieses Problem auch ohne die Funktionsaufrufe verursachen? Der Vergleich der Datumsspalte (indexiert, nicht in Funktionen eingeschlossen) mit SYSDATE verwendet den Index.

Vergleicht man zwei Spalten, die erste ist Primärschlüssel und die zweite ist NICHT INDEXED, führt zu einem vollständigen Scan (verursacht durch den Vergleich, ohne Funktionen um jede Spalte).

Hilft ein Index für die andere Spalte (zusätzlich zum Primärschlüssel in der ersten Spalte) mit einem Ungleichheitsfilter? Antwort: Nein. Nachdem Sie einen Index für die zweite Spalte erstellt und EXPLAIN PLAN erneut ausgeführt haben, wird die Tabelle weiterhin vollständig gescannt. Genau wie Gordon erklärte.