Sonntag, März 20, 2011

Extended Statistics

Vor ein paar Tagen hatte ich darüber nachgedacht, mich etwas genauer über das Thema Extended Statistics zu informieren - und schon hat Maria Colgan darüber einen neuen Artikel im cbo Entwickler Blog geschrieben.

Grundsätzlich dienen Extended Statistics dazu, um dem cbo Informationen über die Abhängigkeit von Werten mehrerer Spalten zu geben: da der cbo überlicherweise von vollständiger Unabhängigkeit der Werte ausgeht, kommt er ohne diesen Hinweis zu einer Überschätzung der Selektivität von Einschränkungen. Dier Erfassung der Statistiken erfolgt auf Basis von virtual columns.

Nachtrag 24.03.2011: in einem weiteren Artikel erläutert Frau Colgan auch noch, wie in 11.2 mögliche Kandidaten für Extended Statistics automatisch bestimmt werden können.

Nachtrag 18.11.2011: für die virtuelle Spalte, die die Spaltenkombination der extended statistics repräsentiert, sollten Histogramme erzeugt werden, da sonst weiterhin die Statisiken der Einzelspalten herangezogen werden, wenn für sie Histogramme existieren (oder kurz: Histogramme haben Vorrang vor extended statistics). Auch diese Auskunft findet man in Frau Colgans Artikel.

Mittwoch, März 16, 2011

numwidth

Schon erstaunlich, wie viele Dinge es gibt, die ich über sqlplus nicht weiß - obwohl ich das Tool seit zehn Jahren nahezu täglich nutze. Vor kurzem hatte Eddie Awad ein paar recht interessante show-Optionen erwähnt, aber viel überraschender war für mich, dass sqlplus Nachkommastellen nur bis zu einer bestimmten Anzahl darstellt. Bisher habe ich offenbar nie mehr Stellen als den default-Wert (10) benötigt ...

drop table number_test;

create table number_test (a number (13,12));

insert into number_test values (.99999);
insert into number_test values (.999999);
insert into number_test values (.9999999);
insert into number_test values (.99999999);
insert into number_test values (.999999999);
insert into number_test values (.9999999999);
insert into number_test values (.99999999999);
insert into number_test values (.999999999999);
insert into number_test values (.9999999999999);
insert into number_test values (.99999999999999);
insert into number_test values (.999999999999999);
select length(a), vsize(a), a from number_test;

set numwidth 12

select length(a), vsize(a), a 
  from number_test;

   LENGTH(A)     VSIZE(A)            A
------------ ------------ ------------
           6            4       ,99999
           7            4      ,999999
           8            5     ,9999999
           9            5    ,99999999
          10            6   ,999999999
          11            6  ,9999999999
          12            7 ,99999999999
          13            7            1
           1            2            1
           1            2            1
           1            2            1

11 Zeilen ausgewählt.

set numwidth 8

select length(a), vsize(a), a 
  from number_test;

LENGTH(A) VSIZE(A)        A
--------- -------- --------
        6        4   ,99999
        7        4  ,999999
        8        5 ,9999999
        9        5        1
       10        6        1
       11        6        1
       12        7        1
       13        7        1
        1        2        1
        1        2        1
        1        2        1

11 Zeilen ausgewählt.

Montag, März 14, 2011

Oracle DWH Best Practices

Von Maria Colgan, die ein paar sehr interessante Artikel im Blog der cbo Entwickler geschrieben hat, gibt es ein White-Paper Best Practices for a Data Warehouse on Oracle Database 11g, das eine ganze Reihe wichtiger Basisinformationen zum Thema liefert (von der physikalischen über die logische Struktur bis hin zu Partitionierungsstrategien, Statistikerfassung und Zugriffsanalyse).

Sonntag, März 13, 2011

Inhalte von OS-Directories über External Table anzeigen - 2

Nachdem ich bei einem Kunden gesehen hatte, wie leicht man die Liste der in einem OS-Verzeichnis vorliegenden Dateien in 11g über External Tables anzeigen kann, und hier einen Link zu Adrian Billingtons Erläuterung des Features unterbrachte, folgt nun ein praktisches Beispiel für 11.2 und Windows 7 (basierend auf den Ausführungen des Herrn Billington):

Zunächst benötigt man ein Directory-Objekt, das auf ein OS-Verzeichnis verweist:

create directory data_dir as 'c:\temp';

In diesem Verzeichnis legt man nun eine Batch-Datei an - hier directory_list.bat - , die den Befehl zur Anzeige der Verzeichnis-Inhalte enthält:

@echo off
dir /N c:\temp

In der Datenbank kann man nun eine External Table anlegen, die die Batch-Datei über einen PREPROCESSOR-Befehl ausführt:

CREATE TABLE directory_list
( file_date VARCHAR2(50)
, file_time VARCHAR2(50)
, file_size VARCHAR2(50)
, file_name VARCHAR2(255)
)
ORGANIZATION EXTERNAL
(
  TYPE ORACLE_LOADER
  DEFAULT DIRECTORY data_dir
  ACCESS PARAMETERS
  (
     RECORDS DELIMITED BY NEWLINE
     LOAD WHEN file_size != '
'
     PREPROCESSOR data_dir: 'directory_list.bat'
     FIELDS TERMINATED BY WHITESPACE
  )
  LOCATION ('test.txt')
)
REJECT LIMIT UNLIMITED;

Da die External Table neben den Datei-Informationen auch noch Header- und Footer-Elemente enthält, ist es sinnvoll, diese Anteile mit Hilfe einer View zu filtern:

CREATE VIEW dir_list
AS
SELECT file_name
     , to_char(TO_DATE(file_date||','||file_time,'DD/MM/YYYY HH24:MI'), 'dd.mm.yyyy hh24:mi:ss') AS file_time
     , TO_NUMBER(file_size,
             'fm999,999,999,999') AS file_size
  FROM directory_list
 WHERE REGEXP_LIKE( file_date, '[0-9]{2}.[0-9]{2}.[0-9]{4}');

Die erzeugte View enthält dann die Informationen des DIR-Kommandos:

FILE_NAME                                FILE_TIME            FILE_SIZE
---------------------------------------- ------------------- ----------
directory_list.bat                       01.03.2011 20:28:00         25
DIRECTORY_LIST_3192_3532.bad             13.03.2011 15:10:00         62
DIRECTORY_LIST_3192_3532.dsc             13.03.2011 15:10:00        149
DIRECTORY_LIST_3192_3532.log             13.03.2011 15:10:00       3152
DIRECTORY_LIST_3932_3424.bad             01.03.2011 20:31:00         62
DIRECTORY_LIST_3932_3424.dsc             01.03.2011 20:31:00        149
DIRECTORY_LIST_3932_3424.log             01.03.2011 20:31:00      14380
EXT_UPTIME_3416_2432.bad                 16.02.2011 14:32:00         62
EXT_UPTIME_3416_2432.log                 16.02.2011 14:32:00       6433
EXT_UPTIME_412_1316.bad                  15.02.2011 20:55:00         65
EXT_UPTIME_412_1316.log                  15.02.2011 20:55:00        919
EXT_UPTIME_412_2632.bad                  15.02.2011 21:23:00         65
EXT_UPTIME_412_2632.log                  15.02.2011 21:23:00      22975
test.txt                                 01.03.2011 20:16:00          0
uptime.csv                               16.02.2011 14:11:00      30258
uptime_.csv                              15.02.2011 20:41:00      54541

Nützlich ist eine solche Möglichkeit z.B. dann, wenn man keinen direkten Zugriff auf den Serverrechner besitzt.

Mittwoch, März 02, 2011

Planüberschreibung mit DBMS_SPM

Im Blog der cbo-Entwickler zeigt Maria Colgan, wie man ein mit irreführenden Hints versehenes SQL-Statement einer 3rd Party Applikation auf einen Plan ohne Hints umleiten kann. Basis des Verfahrens sind das SQL Plan Management (SPM) und das zugehörige Package DBMS_SPM.

Result Caching

Einmal mehr hat Rob van Wijk einen interessanten Blog-Eintrag zu einem Thema geschrieben, mit dem ich mich noch nicht ernsthaft beschäftigt habe: nämlich zum result cache in 11g. Wahrscheinlich wäre die dort verlinkte Präsentation sogar noch interessanter.

Dienstag, März 01, 2011

Inhalte von OS-Directories über External Table anzeigen

Adrian Billington erläutert hier, wie man die Inhalte eines Betriebssystem-Verzeichnisses via External Table anzeigen lassen kann. Voraussetzung für das Verfahren ist Oracle 11, da man den preprocessor dieser Version benötigt.

Set Role

Nur als kurze Notiz: gestern habe ich mir für einen Account die SELECT_CATALOG_ROLE geben lassen und war dann leicht verwundert, dass ich trotzdem nicht auf v$- und data dictionary Views zugreifen konnte. Noch mehr überraschte mich, dass ich die Views in all_objects sogar sehen konnte - nur eben nicht abfragen. Eine kurze Google-Recherche ergab dann, dass die Rolle offenbar nicht als default-Rolle definiert war und deshalb in der Session explizit aktiviert werden musste (der Hinweis fand sich in einem Foren-Beitrag von Joel Garry); vermutlich habe ich das irgendwann mal gewusst, aber wieder komplett vergessen. Das Vorgehen zur Aktivierung ist:

-- Prüfung, ob die Rollen aktiviert sind
select *
  from session_roles;
--> lieferte kein Ergebnis

set role none;
--> Deaktivierung aller Rollen: zu testen wäre noch, ob das tatsächlich nötig ist

set role all;
--> Aktivierung aller Rollen; hier könnte man auch einzelne Rollen aktivieren
--   (während die Deaktivierung nur für alle Rollen durchführbar ist)

Die Oracle-Doku erläutert die zugrunde liegende Idee dann in aller wünschenswerten Klarheit:
When a user logs on to Oracle Database, the database enables all privileges granted explicitly to the user and all privileges in the user's default roles. During the session, the user or an application can use the SET ROLE statement any number of times to enable or disable the roles currently enabled for the session.
Weitere Details liefert wie immer auch die PSOUG-Referenz.

Was mich allerdings wundert, ist, dass die Rolle nach der Zuweisung nicht automatisch als default betrachtet wurde. Das wäre gelegentlich noch zu überprüfen.