Mittwoch, August 20, 2014

drop table people

Wenn es bei xkcd einen Strip mit SQL-Queries gibt, muss er hier verlinkt werden - auch wenn's vielleicht eher um ein philosophisches Problem geht.

Dienstag, August 12, 2014

Definition von AWR Intervallen

Doug Burns hat dieser Tage in seinem Blog zwei Artikel zum Thema der Definition von AWR Intervallen veröffentlicht. Erinnerungswürdig scheinen mir dabei vor allem die folgenden beiden Punkte:
  • in einem produktiven System ist es sinnvoll, die Retention der AWR Snapshots auf einen deutlich höheren Wert als den default von 8 Tagen zu setzen (35-42 Tage oder gleich: unbegrenzt). 
  • weniger sinnvoll ist es, die AWR Intervalle selbst zu verkürzen: also vom Standard-Intervall von 1h auf 15 oder 30 min zu gehen. Die Begründung dieser Empfehlung ist, dass es zum Zweck der detaillierten Analyse andere geeignetere Tools gibt (ASH, SQL Monitoring), während AWR eher zur globalen Analyse des Systemverhaltens gedacht ist, und in diesem Fall erschweren kleinere Intervalle die Auswertung.
Das halte ich für einleuchtend.

Freitag, August 08, 2014

APPROX_COUNT_DISTINCT

Eigentlich stand auf meinem Erledigungszettel die Idee, eine kurze Untersuchung der in 12.1.0.2 neu eingeführten APPROX_COUNT_DISTINCT Funktion durchzuführen, mit deren Hilfe man die ungefähre Anzahl der distinkter Werte in einer Spalte effizient ermitteln können soll - aber Luca Canali hat gerade einen entsprechenden Artikel veröffentlicht und so genau wie der Herr Canali hätte ich mir den Fall ohnehin nicht angeschaut. Hingewiesen wird im Artikel unter anderem auf folgende Punkte:
  • beim count(distinct column_value) hängt die Performance entscheidend von der Notwendigkeit großer Sortierungen ab - und damit von der Spaltenbreite und der Anzahl distinkter Werte: je breiter die Spalten und je näher die Anzahl unterschiedlicher Werte an die Satzanzahl heranreicht, desto teurer werden die Sortierungen (inklusive temp I/O waits).
  • APPROX_COUNT_DISTINCT basiert auf einem Verfahren, dass eine geringe Memory-Nutzung erfordert und das gut skaliert. Bezahlt wird diese Optimierung mit einem Verzicht auf vollständige Genauigkeit: wie der Name der Funktion schon andeutet, wird nicht gezählt, sondern überschlagen.
  • In den Tests des Herrn Canali ergibt sich eine massive Beschleunigung der Operationen bei einer recht hohen Genauigkeit. Dabei betrifft die Beschleunigung natürlich in erster Linie die Fälle, in denen das exakte Zählen kostspielig wird (also: viele distinkte Werte, breite Spalten) - für Spalten mit sehr niedriger Kardinalität nähert sich die Laufzeit beider Operationen der Zeit, die für das Lesen der Daten (über FTS oder IFFS) benötigt wird.
  • der APPROX_COUNT_DISTINCT-Aufruf lässt sich sehr gut parallelisieren.
  • hinter der neuen Funktion steht der HyperLogLog (HLL) Algorithmus, den Alex Fatkulin (in einem bei Luca Canali verlinkten Artikel) folgendermaßen erläutert: "in a nutshell, it relies on counting the number of trailing (or leading) zeroes in the binary stream and using that information to estimate number of unique values with a very high degree of accuracy."
  • im Flame Graph der Operation (ohne den zu ergänzen der Herr Canali dieser Tage keinen Artikel beendet) findet man den Aufruf von qesandvHllAdd.
  • nicht ganz klar ist mir, ob der verwendete Algorithmus mit dem des in der Statistikerzeugung verwendeten approximate NDV identisch ist - Christian Antognini scheint das zu verneinen.
Für geeignete Fragestellungen sollte die Funktion jedenfalls ziemlich nützlich sein.

Donnerstag, August 07, 2014

ALTER INDEX ... COMPUTE STATISTICS ist wirklich deprecated...

Im OTN-Forum wurde dieser Tage die Frage gestellt, ob nach einem Index-Aufbau ein expliziter Neuaufbau von Statistiken erforderlich ist. In einem Kommentar erwähnte ein Diskussionsteilnehmer sein Standardverfahren des Aufrufs von ALTER INDEX ... COMPUTE STATISTICS nach dem Index-Aufbau. Nun hatte ich eine relativ klare Vorstellung von den Unterschieden bei der Statistikerstellung unter Verwendung des (veralteten) ANALYZE-Kommandos (für Tabellen) und dem (aktuellen) Aufruf von DBMS_STATS.GATHER_TABLE - aber keine Ahnung, wie die Statistiken aussehen, die durch ALTER INDEX ... COMPUTE STATISTICS erzeugt werden. Ein Test zeigt ein recht drastisches Ergebnis: offenbar leistet die COMPUTE STATISTICS-Option des ALTER INDEX-Kommandos in 11.2 rein gar nichts:

-- 11.2.0.1
-- drop test table
drop table t;
 
-- create test table
create table t
as
select rownum id
    , mod(rownum, 10) col1
  from dual
connect by level <= 100000;
 
-- delete a lot of rows
create index t_idx on t(id);
delete from t where col1 <= 5;
commit;
 
-- statistics after object creation and delete
select index_name, num_rows, leaf_blocks, last_analyzed from user_indexes where index_name = 'T_IDX';
 
INDEX_NAME                      NUM_ROWS LEAF_BLOCKS LAST_ANALYZED
----------------------------- ---------- ----------- -------------------
T_IDX                             100000         222 04.08.2014 19:59:22
 
-- table stats deleted
exec dbms_stats.delete_table_stats(user, 't')
 
select index_name, num_rows, leaf_blocks, last_analyzed from user_indexes where index_name = 'T_IDX';
 
INDEX_NAME                      NUM_ROWS LEAF_BLOCKS LAST_ANALYZED
----------------------------- ---------- ----------- -------------------
T_IDX
 
-- alter index compute statistics;
alter index t_idx compute statistics;
 
select index_name, num_rows, leaf_blocks, last_analyzed from user_indexes where index_name = 'T_IDX';
 
INDEX_NAME                      NUM_ROWS LEAF_BLOCKS LAST_ANALYZED
----------------------------- ---------- ----------- -------------------
T_IDX
 
-- dbms_stats
exec dbms_stats.gather_table_stats(user, 't', cascade=>true)
 
select index_name, num_rows, leaf_blocks, last_analyzed from user_indexes where index_name = 'T_IDX';
 
INDEX_NAME                      NUM_ROWS LEAF_BLOCKS LAST_ANALYZED
----------------------------- ---------- ----------- -------------------
T_IDX                              40000         222 04.08.2014 19:59:24

Eine ganz so große Überraschung ist dieses Verhalten allerdings insofern nicht, als bereits die Dokumentation zu 10.2 erklärte:
COMPUTE STATISTICS Clause: This clause has been deprecated. Oracle Database now automatically collects statistics during index creation and rebuild. This clause is supported for backward compatibility and will not cause errors.
In der Dokumentation zu 11g erscheint die Klausel überhaupt nicht mehr.

Freitag, August 01, 2014

SQL Server ETL mit T-SQL oder SSIS

Es ist schon eine Weile her, dass ich ernsthaft mit dem SQL Server gearbeitet habe - und ich bin mir nicht sicher, ob ich ernsthaft behaupten würde, je ernsthaft mit den SQL Server Integration Services (SSIS) gearbeitet zu haben. An Projekten, in denen SSIS eingesetzt wurde, war ich allerdings beteiligt, habe aber immer dafür plädiert, die SSIS in diesem Zusammenhang nur als Container für SQL-Operationen zu verwenden - ganz im Sinne eines älteren Artikels von James Serra, der sich mit den Vorteilen von SSIS und T-SQL im ETL-Zusammenhang beschäftigt, und dort anmerkt:
If you decide T-SQL is the way to go and you just want to execute a bunch of T-SQL statements, it’s still a good idea to wrap them in SSIS Execute SQL Tasks because you can use logging, auditing and error handling that SSIS provides that T-SQL does not.  You can also easily run SSIS Execute SQL Tasks in parallel so you are able to run stored procedures in parallel.
Darüber hinaus liefert der Artikel eine ganze Reihe von Argumenten für und wider die beiden Varianten. Auf die Idee, den Artikel hier zu erwähnen, hat mich die aktuelle Notiz SQL Server Agent job steps vs SSIS gebracht, die neben einem Link auf den älteren Artikel auch noch ein paar zusätzliche Anmerkungen zum SQL Server Agent enthält - was der Titel vielleicht schon andeutet...