Kann Abfrage optimiert werden?

a-town-danny

Neuer Benutzer
Beiträge
3
Hallo zusammen,

ich habe folgende Oracle SQL Abfrage:

SELECT * FROM IIM.MESSWERTE WHERE ID_MESS_STELLE= 1 AND MELDE_ZEIT BETWEEN TO_TIMESTAMP('2017-04-06 00:00:00', 'YYYY-MM-DD HH24:MI:SS') AND TO_TIMESTAMP('2017-04-07 00:00:00', 'YYYY-MM-DD HH24:MI:SS') ORDER BY MELDE_ZEIT;

Die Abfrage benötigt bei 800.000 Datensätzen ca. 8 Sekunden. Kann die Abfrage optimiert werden?

Ich denke, dass das BETWEEN die meiste Zeit benötigt.

Wie kann ich die Abfrage schneller machen? Vielleicht ohne BETWEEN?

Grüße
Danny
 
Werbung:
Was sagt denn Explain (analyze), was hast für Indexe?

Code:
test=# create table messwerte (id serial primary key, ts timestamp, wert numeric);
CREATE TABLE
test=*# insert into messwerte (ts, wert) select '2000-01-01'::timestamp + random() * '1second'::interval * 1000000 from generate_series(1, 1000000) s;
INSERT 0 1000000
test=*# create index idx_ts on messwerte(ts);
CREATE INDEX
test=*# explain analyse select * from messwerte where ts BETWEEN TO_TIMESTAMP('2017-04-06 00:00:00', 'YYYY-MM-DD HH24:MI:SS') AND TO_TIMESTAMP('2017-04-07 00:00:00', 'YYYY-MM-DD HH24:MI:SS') order by ts;
  QUERY PLAN   
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 Sort  (cost=7466.57..7479.07 rows=5000 width=44) (actual time=0.123..0.123 rows=0 loops=1)
  Sort Key: ts
  Sort Method: quicksort  Memory: 25kB
  ->  Bitmap Heap Scan on messwerte  (cost=107.68..7159.38 rows=5000 width=44) (actual time=0.116..0.116 rows=0 loops=1)
  Recheck Cond: ((ts >= to_timestamp('2017-04-06 00:00:00'::text, 'YYYY-MM-DD HH24:MI:SS'::text)) AND (ts <= to_timestamp('2017-04-07 00:00:00'::text, 'YYYY-MM-DD HH24:MI:SS'::text)))
  ->  Bitmap Index Scan on idx_ts  (cost=0.00..106.43 rows=5000 width=0) (actual time=0.113..0.113 rows=0 loops=1)
  Index Cond: ((ts >= to_timestamp('2017-04-06 00:00:00'::text, 'YYYY-MM-DD HH24:MI:SS'::text)) AND (ts <= to_timestamp('2017-04-07 00:00:00'::text, 'YYYY-MM-DD HH24:MI:SS'::text)))
 Planning time: 1.020 ms
 Execution time: 0.166 ms
(9 Zeilen)

test=*#

Also ca. 1,1 Millisekunde für Planung und Ausführung. Ist aber nixt exakt Deine Tabelle. Und ist kein Oracle.
 
Ich kenne Ora nicht, ich weiß nicht so recht, ob das ein Abfrageplan sein soll und falls ja, wie dieser zu interpretieren ist ... immer diese exotischen Dinge ;-)
 
Ich vermute dass das "Table Access (Full)" dein Flaschenhals ist.
http://use-the-index-luke.com/de/sql/ausfuehrungsplaene/oracle/operationen-bedeutung

TABLE ACCESS FULL

Auch bekannt als Full-Table-Scan (FTS). Liest die ganze Tabelle – alle Zeilen – wie gespeichert, das heißt, in „zufälliger“ Reihenfolge. Obwohl die Blöcke nicht einzeln, sondern mehrere auf einmal gelesen werden, gehört TABLE ACCESS FULL zu den teuersten Operationen überhaupt. Neben der Last am Speichersystem ist ein Full-Table-Scan auch sehr CPU-intensiv, da alle Tabellenzeilen gegen die where-Klausel geprüft werden müssen. Siehe auch Full-Table-Scan.

Aber 100% kann ich das nicht sagen.
 
Werbung:
Hi,

aus dem Plan sind jetzt die Cardinalitäten nicht erkennbar, aber ein erster Schritt wäre ein Index auf MELDE_ZEIT:
Code:
CREATE INDEX MELDE_ZEIT_IX ON MESSWERTE(MELDE_ZEIT);
Je nachdem, wie viele Unterschiedliche Werte es für ID_MESS_STELLE gibt, könnte man die Spalte auch noch an erster Stelle aufnehmen. Wenn die Spalte nur wenig selektiv ist kann man es so lassen.
 
Zurück
Oben