Analizuję plany wykonania Oracle i odkryłem zadziwiający fakt. Sprawdź to zapytanie. Podpowiedź jest tylko do wyświetlania, że mam indeksu i będę oczekiwać Oracle wykorzystać go do skanowania zakres:Nieistotna różnica w planie wykonania z Oracle przy użyciu znacznika czasu jdbc lub daty
// execute_at is of type DATE.
PreparedStatement stmt = connection.prepareStatement(
"SELECT /*+ index(my_table my_index) */ * " +
"FROM my_table " +
"WHERE execute_at > ? AND execute_at < ?");
Te dwa wiązania skutkują zupełnie innego zachowania (w celu wykluczenia powiązać zmiennej problemy zerkanie, faktycznie egzekwowane dwa twardych Analizuje):
// 1. with timestamps
stmt.setTimestamp(1, start);
stmt.setTimestamp(2, end);
// 2. with dates
stmt.setDate(1, start);
stmt.setDate(2, end);
1) za pomocą znaczników czasu, dostaję INDEX FULL SCAN
a zatem orzeczenie filtr
--------------------------------------------------------------
| Id | Operation | Name |
--------------------------------------------------------------
| 0 | SELECT STATEMENT | |
|* 1 | FILTER | |
| 2 | TABLE ACCESS BY INDEX ROWID| my_table |
|* 3 | INDEX FULL SCAN | my_index |
--------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter(:1<:2)"
3 - filter((INTERNAL_FUNCTION(""EXECUTE_AT"")>:1 AND
INTERNAL_FUNCTION(""EXECUTE_AT"")<:2))
2) z datami, otrzymuję dużo lepiej INDEX RANGE SCAN
oraz dostęp orzecznik
--------------------------------------------------------------
| Id | Operation | Name |
--------------------------------------------------------------
| 0 | SELECT STATEMENT | |
|* 1 | FILTER | |
| 2 | TABLE ACCESS BY INDEX ROWID| my_table |
|* 3 | INDEX RANGE SCAN | my_index |
--------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter(:1<:2)"
3 - access(""EXECUTE_AT"">:1 AND ""EXECUTE_AT""<:2)
Teraz mój przykład jest tylko przykładem. Prawdziwe zapytanie jest o wiele bardziej skomplikowane, gdzie niezbędne jest posiadanie RANGE SCANS
lub UNIQUE SCANS
(w zależności od predykatu) zamiast FULL SCANS
.
Czy jest tu coś, czego nie rozumiem? Czy ktoś może wskazać mi najlepsze rozwiązanie/praktykę? Ponieważ w świecie Java uważam, że java.sql.Timestamp
jest o wiele bardziej odpowiedni, ale większość naszych kolumn ma typ Oracle: DATE
. Używamy Java 6 i Oracle 11g
Uwaga, znalazłem podobne pytanie tutaj: http://stackoverflow.com/questions/1945603/why- is-oracle-so-slow-when-i-pass-a-java-sql-timestamp-for-date-column/6620643 –