<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-17143762</id><updated>2012-02-16T09:26:17.495-08:00</updated><category term='Datenmodell'/><category term='Analytics'/><category term='Virtual Columns'/><category term='Materialized Views'/><category term='Join'/><category term='Export'/><category term='SQL'/><category term='ETL'/><category term='PCTFREE'/><category term='Buffer Cache'/><category term='Trigger'/><category term='Data Dictionary'/><category term='Statistik'/><category term='PL/SQL'/><category term='SQL Server'/><category term='Model'/><category term='SQL*Net'/><category term='Bug'/><category term='Result Cache'/><category term='DBFMBRC'/><category term='Windows'/><category term='Security'/><category term='Sort'/><category term='SCN'/><category term='Postgres'/><category term='Trace'/><category term='ASH'/><category term='Undo'/><category term='Zitate'/><category term='Statistiken'/><category term='Administration'/><category term='Plan Management'/><category term='ITL'/><category term='DB-Link'/><category term='Rollen'/><category term='RAC'/><category term='Parallel'/><category term='Pipelined Functions'/><category term='Grouping'/><category term='Dokumentation'/><category term='Index'/><category term='Access Advisor'/><category term='Scripts'/><category term='Blocks'/><category term='Temporary Tablespace'/><category term='FTS'/><category term='Data Warehouse'/><category term='Blogs'/><category term='Tablespaces'/><category term='Advanced Query Rewrite'/><category term='SQLPLUS'/><category term='Cost'/><category term='DB Console'/><category term='Privat'/><category term='Histograms'/><category term='CBO'/><category term='Hints'/><category term='Lock'/><category term='Partitioning'/><category term='Recovery'/><category term='Logging'/><category term='Star Transformation'/><category term='Datentypen'/><category term='Latches'/><category term='Flashback'/><category term='NoSQL'/><category term='ASSM'/><category term='Lob'/><category term='Compression'/><category term='Subquery Factoring'/><category term='Row Migration'/><category term='DML'/><category term='Shrink'/><category term='Number'/><category term='Bitmap Index'/><category term='Workarea'/><category term='External Tables'/><category term='Long'/><category term='Releases'/><category term='SSD'/><category term='DB2'/><category term='SSAS'/><category term='Bücher'/><category term='Tools'/><category term='Hardware'/><category term='Memory'/><category term='Redo'/><category term='MDX'/><category term='Audit'/><category term='OS'/><category term='Excel'/><title type='text'>MP Oracle Blog</title><subtitle type='html'>Notizen zu Datenbankthemen</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default?start-index=101&amp;max-results=100'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>410</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-17143762.post-4104421070546283218</id><published>2012-02-15T01:56:00.000-08:00</published><updated>2012-02-15T01:58:46.988-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Analytics'/><category scheme='http://www.blogger.com/atom/ns#' term='Sort'/><category scheme='http://www.blogger.com/atom/ns#' term='Data Dictionary'/><title type='text'>Fortschrittsangaben in v$session_longops</title><content type='html'>Heute ist mir zum ersten Mal aufgefallen, dass in v$session_longops nicht unbedingt immer plausible Angaben erscheinen:&lt;br /&gt;&lt;br /&gt;&lt;div class="codesnippet"&gt;&lt;pre&gt;   SOFAR  TOTALWORK MESSAGE                                             SQL_PLAN_OPERATION  SQL_PLAN_OPTIONS &lt;br /&gt;-------- ---------- --------------------------------------------------- ------------------- -----------------&lt;br /&gt; 1138348     861414 Sort Output:  : 1138348 out of 861414 Blocks done   WINDOW              SORT             &lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;Entsprechend zeigt auch DBMS_SQLTUNE.REPORT_SQL_MONITOR einen &lt;i&gt;Progress&lt;/i&gt; von deutlich über 100%. Es handelt sich dabei um eine WINDOW SORT Operation einer analytischen Funktion, also nicht um einen Wert der mit dbms_application_info.set_session_longops eingefügt wurde, sondern um interne Operationsangaben.&lt;br /&gt;&lt;br /&gt;Davon abgesehen deutet sich mal wieder an, dass man mit Analytics auf großen Datenmengen vorsichtig sein sollte, da die WINDOW SORT Operation nicht ganz unproblematisch ist - wozu &lt;a href="http://jonathanlewis.wordpress.com/2009/09/07/analytic-agony/"&gt;Jonathan Lewis&lt;/a&gt; Grundsätzliches gesagt hat; zwei Randbemerkungen zum Thema habe ich &lt;a href="http://martinpreiss.blogspot.com/2011/01/performance-von-analytics.html"&gt;hier&lt;/a&gt; und &lt;a href="http://martinpreiss.blogspot.com/2011/01/direct-path-read-temp-mit-cnt1.html"&gt;hier&lt;/a&gt; gegeben. In solchen Fällen gehe ich unter Umständen auf die Verwendung eines Joins der Basistabelle mit einem aggregierten Zwischenergebnis zurück.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-4104421070546283218?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/4104421070546283218/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2012/02/fortschrittsangaben-in-vsessionlongops.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/4104421070546283218'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/4104421070546283218'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2012/02/fortschrittsangaben-in-vsessionlongops.html' title='Fortschrittsangaben in v$session_longops'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-8381983809085941874</id><published>2012-02-12T08:00:00.000-08:00</published><updated>2012-02-12T08:00:17.787-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PL/SQL'/><title type='text'>DBMS_SCHEDULER-Visualisierung mit SQL Developer 3.1</title><content type='html'>Tim Hall, der vor ein paar Jahren ein ganzes &lt;a href="http://www.amazon.com/Oracle-Job-Scheduling-dbms_scheduler--Focus/dp/0974448664/ref=sr_1_5?ie=UTF8&amp;amp;qid=1329062162&amp;amp;sr=8-5"&gt;Buch&lt;/a&gt; zu DBMS_JOBS und DBMS_SCHEDULER geschrieben hat, zeigt in seinem &lt;a href="http://www.oracle-base.com/articles/misc/SqlDeveloper31SchedulerSupport.php"&gt;Blog&lt;/a&gt;, was der aktuelle SQL Developer 3.1 zu Scheduler-Jobs und Job-Ketten anzubieten hat und liefert dabei auch noch eine Reihe von Links auf weitere Artikel zum Thema Scheduler. Sein Fazit lautet: "I would currently define all job chains using the PL/SQL API, so I could save my creation script in source control, and just use the SQL Developer interface to view the job chains I've created. With a bit of luck, this situation will change in subsequent versions."&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-8381983809085941874?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/8381983809085941874/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2012/02/dbmsscheduler-visualisierung-mit-sql.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/8381983809085941874'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/8381983809085941874'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2012/02/dbmsscheduler-visualisierung-mit-sql.html' title='DBMS_SCHEDULER-Visualisierung mit SQL Developer 3.1'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-4942687889501858270</id><published>2012-02-09T12:14:00.000-08:00</published><updated>2012-02-09T12:14:45.920-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tools'/><title type='text'>I/O-Tests</title><content type='html'>Kevin Closson überfordert mich häufig bereits mit den Titeln seiner Blog-Artikel - und nicht selten auch mit den Inhalten - aber diesmal verstehe ich, dass er sein bewährtes SLOB-Tool (&lt;a href="http://kevinclosson.wordpress.com/2012/02/06/introducing-slob-the-silly-little-oracle-benchmark/"&gt;The Silly Little Oracle Benchmark&lt;/a&gt;) vorstellt, das offenbar deutlich mehr kann als das Orion-Tool (das dort auch verlinkt ist).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-4942687889501858270?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/4942687889501858270/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2012/02/io-tests.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/4942687889501858270'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/4942687889501858270'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2012/02/io-tests.html' title='I/O-Tests'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-6924015161361254732</id><published>2012-02-07T12:30:00.000-08:00</published><updated>2012-02-07T12:30:07.043-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='CBO'/><title type='text'>Plan-Interpretation</title><content type='html'>Christian Antogninis Erläuterungen zur Interpretation von &lt;i&gt;Execution Plans&lt;/i&gt;, die man in Kapitel 6 seines großartigen Buches &lt;i&gt;Troubleshooting Oracle Performance&lt;/i&gt; und - in knapper Form - auch im &lt;a href="http://antognini.ch/papers/InterpretingExecutionPlans_20091017.pdf"&gt;Web&lt;/a&gt; findet, gehören für mich zu den wichtigsten Grundlagen für die Deutung von SQL-Zugriffen. Im Blog-Eintrag &lt;a href="http://antognini.ch/2012/02/index-scan-with-filter-predicate-based-on-a-subquery/"&gt;Index Scan with Filter Predicate Based on a Subquery&lt;/a&gt; zeigt der Autor jetzt einen jener Fälle, in denen die allgemeinen Interpretationsregeln nicht gelten. Sein Fazit lautet: "In summary, be careful when you see an index scan with a filter predicate applying a subquery. The execution plan might not be carried out as you expect at first sight. It is also essential to point out that in such a case the predicate information is essential to fully understand what’s going on." Auf die Prädikat-Informationen würde ich aber bei der Plandeutung ohnehin selten verzichten wollen, da sie für die Überprüfung von Cardinality-Schätzungen entscheidend sind.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-6924015161361254732?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/6924015161361254732/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2012/02/plan-interpretation.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/6924015161361254732'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/6924015161361254732'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2012/02/plan-interpretation.html' title='Plan-Interpretation'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-6838442227263942690</id><published>2012-02-07T11:05:00.000-08:00</published><updated>2012-02-09T13:00:17.595-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Partitioning'/><title type='text'>Interval Partitioninig und das Ende aller Tage</title><content type='html'>Dass das&lt;i&gt;&amp;nbsp;Interval Partitioning&lt;/i&gt;&amp;nbsp;leider noch ein paar unerfreuliche Bugs enthält, habe ich&amp;nbsp;&lt;a href="http://martinpreiss.blogspot.com/2011/12/ora-08176-mit-merge-und-interval.html"&gt;gelegentlich&amp;nbsp;schon mal erwähnt&lt;/a&gt;.&amp;nbsp;Heute ist mir aufgefallen, dass die Verwendung des sehr beliebten Datums-Default-Werts '31.12.9999' bei einer nach einer Datumsangabe intervall partitionierten Tabelle nicht ganz das gewünschte Ergebnis bringt:&lt;br /&gt;&lt;br /&gt;&lt;div class="codesnippet"&gt;&lt;pre&gt;create table test_interval_max_default ( mydate date)&lt;br /&gt;partition by range (mydate)&lt;br /&gt;interval (NUMTOYMINTERVAL(1,'MONTH'))&lt;br /&gt;(partition test_p1 values less than (to_date('20120201', 'yyyymmdd')));&lt;br /&gt;&lt;br /&gt;Tabelle wurde erstellt.&lt;br /&gt;&lt;br /&gt;insert into test_interval_max_default (mydate) values (to_date('30.11.9999', 'dd.mm.yyyy'));&lt;br /&gt;&lt;br /&gt;1 Zeile wurde erstellt.&lt;br /&gt;&lt;br /&gt;insert into test_interval_max_default (mydate) values (to_date('01.12.9999', 'dd.mm.yyyy'));&lt;br /&gt;&lt;br /&gt;insert into test_interval_max_default (mydate) values (to_date('01.12.9999', 'dd.mm.yyyy'))&lt;br /&gt;            *&lt;br /&gt;FEHLER in Zeile 1:&lt;br /&gt;ORA-01841: (Volles) Jahr muss zwischen -4713 und +9999 liegen und darf nicht 0 sein&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;Nun ist&amp;nbsp;'31.12.9999' sicher ein ziemlich unglücklicher Default-Wert - nicht zuletzt, weil er den CBO, der in Abwesenheit von Histogrammen eine Gleichverteilung der Werte zwischen Minimum und Maximum annimmt, zur massiven Fehleinschätzung von Kardinalitäten führen kann -, aber dass man ihn einfach nicht einfügen kann, erscheint doch etwas drastisch. In diesem Fall handelt es sich aber nicht um einen Bug, sondern um &lt;a href="http://docs.oracle.com/cd/E18283_01/server.112/e16541/part_admin001.htm#insertedID2"&gt;ein dokumentiertes Verhalten&lt;/a&gt;:&lt;br /&gt;&lt;blockquote class="tr_bq"&gt;Note, however, that using a date where the high or low bound of the partition would be out of the range set for storage causes an error. For example, TO_DATE('9999-12-01', 'YYYY-MM-DD') causes the high bound to be 10000-01-01, which would not be storable if 10000 is out of the legal range.&lt;/blockquote&gt;Es bleibt also nur die Verwendung eines anderen Default-Werts für "das Ende aller Tage" oder der Verzicht auf &lt;i&gt;Interval Partitioning&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Nachtrag 09.02.2012&lt;/b&gt;: Der Fall ist tatsächlich sogar noch unerfreulicher: bereits eine Query mit einer entsprechenden Bedingung ruft ora-01841 hervor:&lt;br /&gt;&lt;div class="codesnippet"&gt;&lt;pre&gt;SQL&amp;gt; select * from test_interval_max_default where mydate = to_date('31.12.9999', 'dd.mm.yyyy');&lt;br /&gt;select * from test_interval_max_default where mydate = to_date('31.12.9999', 'dd.mm.yyyy')&lt;br /&gt;              *&lt;br /&gt;FEHLER in Zeile 1:&lt;br /&gt;ORA-01841: (Volles) Jahr muss zwischen -4713 und +9999 liegen und darf nicht 0 sein&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;Angesichts dieses Verhaltens schwindet meine Zuneigung zum &lt;i&gt;Interval Partitioning&lt;/i&gt; allmählich - obwohl es eigentlich eine so schöne Idee ist. Nun ja, vielleicht funktioniert es mit Version 12 oder 14.&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-6838442227263942690?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/6838442227263942690/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2012/02/interval-partitioninig-und-das-ende.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/6838442227263942690'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/6838442227263942690'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2012/02/interval-partitioninig-und-das-ende.html' title='Interval Partitioninig und das Ende aller Tage'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-2402731023483724581</id><published>2012-02-05T07:50:00.000-08:00</published><updated>2012-02-05T07:53:40.126-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Cost'/><category scheme='http://www.blogger.com/atom/ns#' term='Index'/><title type='text'>Fehlerhaftes Costing für Index Hash Joins</title><content type='html'>Jonathan Lewis zeigt in seinem &lt;a href="http://jonathanlewis.wordpress.com/2012/01/30/index-hash/"&gt;Blog&lt;/a&gt;, dass die Kostenberechnung für &lt;i&gt;Index Hash Joins&lt;/i&gt; in allen aktuellen Oracle-Releases massive Fehler enthält, was zur Folge haben kann, dass diese - in manchen Fällen sehr effiziente - Zugriffsoption nicht in Betracht gezogen wird: "This means the optimizer may be missing opportunities where the index  hash join is a good execution path. Keep an eye open for this, you may  want to hint some of your SQL (and then switch the hints into SQL  Baselines, if you’re running 11g)." Ein Aspekt dabei ist, dass Indizes anhand ihrer Benamung ausgewählt werden, ein anderer, dass die Kosten der Einzelschritte nicht sinnvoll summiert werden; außerdem werden für den Index Join zusätzlich zu den erwarteten Kosten eines Index Fast Full Scan&amp;nbsp; noch die Kosten eines Index Full Scan aufgeschlagen, was inhaltlich nicht einleuchtet (und offenbar erst im 10053er Trace sichtbar wird).&lt;br /&gt;&lt;br /&gt;Ich wollte mir noch eine passende Begriffsbestimmung für den &lt;i&gt;Index Hash Join&lt;/i&gt; ausdenken, aber die findet man natürlich auch schon &lt;a href="http://jonathanlewis.wordpress.com/2012/01/30/index-hash/"&gt;beim Herrn Lewis&lt;/a&gt;:&lt;br /&gt;&lt;blockquote class="tr_bq"&gt;One of the less well known access paths available to the optimizer is the &lt;i&gt;&lt;b&gt;“index join”&lt;/b&gt;&lt;/i&gt; also known as the &lt;i&gt;&lt;b&gt;“index hash join”&lt;/b&gt;&lt;/i&gt; path. It’s an access path that can be used when the optimizer decides that it doesn’t need to visit a table to supply the select list because there are indexes on the table that, between them, hold all the required columns.&lt;/blockquote&gt;Und der Vollständigkeit halber dann auch noch ein &lt;a href="http://jonathanlewis.wordpress.com/2010/11/26/index-join-2/"&gt;dritter Link&lt;/a&gt; zum Scratchpad, diesmal auf ein Fallbeispiel, in dem eine Tabelle mehrfach referenziert wird, um den cbo auf die Idee zu bringen, für jeden Fall den geeigneten Index zu verwenden.&lt;br /&gt;&lt;br /&gt;Hier angekommen erinnere ich mich daran, dass ich schon mal auf einen der Index-Join-Artikel verwiesen hatte - und da das dann bereits Teil 4 einer Serie war, ist es vermutlich einfacher gleich auf &lt;a href="http://jonathanlewis.wordpress.com/category/oracle/indexing/index-joins/"&gt;die entsprechende Kategorie im Scratchpad&lt;/a&gt; zu verweisen, die aktuell fünf Artikel enthält.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-2402731023483724581?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/2402731023483724581/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2012/02/fehlerhaftes-costing-fur-index-hash.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/2402731023483724581'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/2402731023483724581'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2012/02/fehlerhaftes-costing-fur-index-hash.html' title='Fehlerhaftes Costing für Index Hash Joins'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-5705036331328499194</id><published>2012-02-03T09:27:00.000-08:00</published><updated>2012-02-07T12:31:30.936-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Trace'/><category scheme='http://www.blogger.com/atom/ns#' term='RAC'/><title type='text'>SQL-Monitor-Darstellungsprobleme im RAC</title><content type='html'>Nur eine kurze Notiz, zu der ich vielleicht gelegentlich die Pointe nachliefern kann: in RAC-Systemen liefert&amp;nbsp;dbms_sqltune.report_sql_monitor - natürlich - nur dann die gewünschten Ergebnisse, wenn man einen sinnvollen Wert für den Parameter INST_ID setzt:&lt;br /&gt;&lt;blockquote class="tr_bq"&gt;INST_ID: Only considers statements started on the specified instance. Use -1 (the default) to target the login instance. NULL will target all instances.&lt;/blockquote&gt;Die NULL-Variante fällt mir erst jetzt auf (und wird dann in der nächsten Woche getestet), aber wenn man den Aufruf für einen anderen Knoten als den, auf dem man sich gerade befindet, ausführt, dann liefert die &lt;i&gt;table function&lt;/i&gt; (zumindest in dem System mit dem ich dieser Tage arbeite) einen relativ unformatierten Plan, in dem die Einrückungen fehlen. Um das zu vermeiden, verbinde ich mich in solchen Fällen direkt mit dem entsprechenden Knoten, aber die Ursache des Verhaltens ist mir unklar - und ich kann ohne größeren Aufwand kein 10046er Trace auf den Maschinen durchführen, um die Unterschiede der beiden Varianten zu bestimmen. Falls NULL hier Abhilfe schafft oder falls mir eine Erklärung über den Weg läuft, trage ich das noch nach.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-5705036331328499194?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/5705036331328499194/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2012/02/sql-monitor-darstellungsprobleme-im-rac.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/5705036331328499194'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/5705036331328499194'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2012/02/sql-monitor-darstellungsprobleme-im-rac.html' title='SQL-Monitor-Darstellungsprobleme im RAC'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-4980359433913297633</id><published>2012-01-31T11:31:00.000-08:00</published><updated>2012-02-02T11:12:23.391-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Bug'/><title type='text'>Bug Fix Links</title><content type='html'>Wenn Jonathan Lewis eine &lt;a href="http://jonathanlewis.wordpress.com/2012/01/31/bug-fixes/"&gt;Liste von Links&lt;/a&gt; erstellt, dann sind diese mit hoher Wahrscheinlichkeit relevant. Im gegebenen Fall geht es um Bug Fixes für aktuelle Oracle Releases.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Nachtrag 02.02.2012&lt;/b&gt;: Interessant ist auch der Hinweis &lt;a href="http://jonathanlewis.wordpress.com/2012/02/01/subquery-factoring/"&gt;eines weiteren Artikels&lt;/a&gt;, dass in 11.2.0.3 diverse Bugs aus dem CTE-Umkreis behoben sind. CTEs sind ein großartiges Mittel um Abfragen übersichtlicher zu gestalten und wenn sie jetzt auch noch robust werden, werde ich sie mit noch größerer Begeisterung einsetzen.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-4980359433913297633?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/4980359433913297633/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2012/01/bug-fix-links.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/4980359433913297633'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/4980359433913297633'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2012/01/bug-fix-links.html' title='Bug Fix Links'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-7235869866293229824</id><published>2012-01-25T22:47:00.000-08:00</published><updated>2012-01-25T22:47:10.704-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='CBO'/><title type='text'>Materialisierung von CTEs</title><content type='html'>&lt;a href="http://orastory.wordpress.com/2012/01/17/materialize/"&gt;Dom Brooks&lt;/a&gt; liefert eine Reihe interessanter Beobachtungen zur Materialisierung von CTEs, die entweder durch den Hint MATERIALIZE oder durch die mehrfache Referenzierung einer solchen Subquery hervorgerufen wird. Unter anderem zeigt er im 10046er Trace die DDL der erzeugten GTT (Global Temporary Table) und erklärt, dass diese Struktur für folgende Ausführungen des Cursors nicht neu erzeugt werden muss (und dass sie sogar für andere Sessions erreichbar ist). Außerdem weist er auf einige zugehörige Bugs im Zusammenhang mit Distributed Transactions hin.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-7235869866293229824?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/7235869866293229824/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2012/01/materialisierung-von-ctes.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/7235869866293229824'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/7235869866293229824'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2012/01/materialisierung-von-ctes.html' title='Materialisierung von CTEs'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-8611709495052362288</id><published>2012-01-25T07:18:00.000-08:00</published><updated>2012-01-25T07:18:03.915-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MDX'/><title type='text'>Execution Plans für DAX</title><content type='html'>Seitdem ich mich mit MDX beschäftige, hoffe ich darauf, über das Stadium der "Optimierung durch Ausprobieren" hinauszukommen. Voraussetzung dafür wären &lt;i&gt;Execution Plans&lt;/i&gt; - aber die sind anscheinend ein Geheimnis der SSAS-Entwickler. Insofern wundere ich mich darüber, dass der SQL Server Profiler für Microsofts neue DAX-Sprache ein Event &lt;i&gt;DAX Query Plan&lt;/i&gt; liefert. Eine Einführung dazu liefert &lt;a href="http://mdxdax.blogspot.com/2011/12/dax-query-plan-part-1-introduction.html"&gt;Jeffrey Wang&lt;/a&gt; - und falls ich mal ernsthaft mit DAX arbeiten sollte, würde mir das vermutlich helfen.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-8611709495052362288?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/8611709495052362288/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2012/01/execution-plans-fur-dax.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/8611709495052362288'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/8611709495052362288'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2012/01/execution-plans-fur-dax.html' title='Execution Plans für DAX'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-3729192154126316670</id><published>2012-01-21T06:26:00.000-08:00</published><updated>2012-01-21T06:26:31.367-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Statistiken'/><title type='text'>Fixed Object Statistics für X$-Objekte</title><content type='html'>&lt;a href="http://blogs.oracle.com/optimizer/entry/fixed_objects_statistics_and_why"&gt;Maria Colgan&lt;/a&gt; schreibt im Blog der CBO-Entwickler über die Bedeutung der Erhebung von Statistiken für Fixed Objects (als X$-Tabellen und -Indizes) mit Hilfe von:&lt;br /&gt;&lt;blockquote class="tr_bq"&gt;DBMS_STATS.GATHER_FIXED_OBJECTS_STATS.&lt;/blockquote&gt;Wichtig sind die Statistiken, da der CBO für die X$-Objekte kein dynamic sampling durchführt, sondern Defaults verwendet, die natürlich in vielen Fällen unpassend sind. Gespeichert werden grundsätzlich die gleichen Statistiken, die auch für normale Tabellen erfasst werden, obwohl die X$-Objekte nur im Memory existieren (daher wird Blocks auf 0 gesetzt). Frau Colgan&amp;nbsp;empfiehlt, die Statistiken unter repräsentativer Workload zu erzeugen. In den Kommentaren beantwortet sie auch noch die Frage, warum diese Statistikerfassung noch nicht &amp;nbsp;automatisiert wurde (die Antwort lautet: sie arbeiten dran, aber der passende Zeitpunkt für die Erfassung ist nicht leicht zu bestimmen). Gelegentlich ergänze ich hier vielleicht noch den Link auf einen Eintrag von Charles Hooper, der das Thema auch schon mal genauer beleuchtet hatte.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-3729192154126316670?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/3729192154126316670/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2012/01/fixed-object-statistics-fur-x-objekte.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/3729192154126316670'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/3729192154126316670'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2012/01/fixed-object-statistics-fur-x-objekte.html' title='Fixed Object Statistics für X$-Objekte'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-4376687846505279597</id><published>2012-01-21T05:52:00.000-08:00</published><updated>2012-01-21T05:52:03.627-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Redo'/><category scheme='http://www.blogger.com/atom/ns#' term='Undo'/><category scheme='http://www.blogger.com/atom/ns#' term='SCN'/><title type='text'>SCN</title><content type='html'>Zuletzt haben sich &lt;a href="http://www.ora-solutions.net/web/2012/01/19/oracle-scn-problem/"&gt;Martin Decker&lt;/a&gt; und &lt;a href="http://orainternals.wordpress.com/2012/01/19/scn-what-why-and-how/"&gt;Riyaj Shamsudeen&lt;/a&gt; ausführlicher zum Thema &lt;i&gt;System Change Number&lt;/i&gt; (SCN) geäußert:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Martin Decker weist auf einen häßlichen Bug hin, der sich ergibt, wenn die SCN ihren Maximalwert erreicht - was unter bestimmten Umständen sehr viel schneller passieren kann, als man angesichts des gigantischen Werteraums, der für sie zur Verfügung steht, erwarten würde.&lt;/li&gt;&lt;li&gt;Bei Riyaj Shamsudeen erfährt man Grundsätzliches zum Thema, beispielsweise zum gerade angesprochenen Wertebereich: "SCN is a huge number with two components to it: Base and wrap. Wrap is a 16 bit number and base is a 32 bit number. It is of the format wrap.base. When the base exceeds 4 billion, then the wrap is incremented by 1. Essentially, wrap counts the number of  times base wrapped around 4 billion." Außerdem wird erläutert, wo die SCN verwendet und wann sie erhöht wird, und auch die Bugs, die der Herr Decker anspricht, werden beleuchtet.&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-4376687846505279597?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/4376687846505279597/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2012/01/scn.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/4376687846505279597'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/4376687846505279597'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2012/01/scn.html' title='SCN'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-8397733608719214151</id><published>2012-01-19T12:45:00.000-08:00</published><updated>2012-01-19T12:45:07.412-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Cost'/><title type='text'>Cost für Scalar Subqueries</title><content type='html'>Dom Brooks weist in seinem &lt;a href="http://orastory.wordpress.com/2012/01/09/scalar-subselect-cost-accounting/"&gt;Blog&lt;/a&gt; darauf hin, dass Oracle auch in aktuellen Releases die Kosten von &lt;i&gt;scalar subqueries&lt;/i&gt; (also Subqueries in der SELECT-Liste, die für jeden einzelnen Ergebnissatz ausgeführt werden) nicht in in die Gesamtkosten einer Query einrechnet (was &lt;a href="http://jonathanlewis.wordpress.com/2007/10/12/scalar-subqueries/"&gt;Jonathan Lewis&lt;/a&gt; in einem verlinkten Artikel damit begründet, dass der cbo nicht schätzen möchte, wie oft diese Unterabfrage ausgeführt wird - obwohl er ja die Menge der Ergebnissätze der Haupt-Query durchaus prognostiziert). Außer auf den Herrn Lewis wird auch noch auf &lt;a href="http://oracle-randolf.blogspot.com/2010/01/when-your-projection-is-not-cost-free.html"&gt;Randolf Geist&lt;/a&gt; (der grundsätzlich darauf hinweist, dass Oracle "obviously treats work that has to be performed as part of the projection differently than work that has to be performed as part of the selection part"; der Fall ist demnach verwandt mit den problematischen Kostenschätzungen für user-defined functions, zu denen der Herr Geist in jüngerer Vergangenheit &lt;a href="http://oracle-randolf.blogspot.com/2011/11/doag-2011-unconference-wrap-up.html"&gt;einiges&lt;/a&gt; &lt;a href="http://oracle-randolf.blogspot.com/2011/12/table-functions-and-join-cardinality.html"&gt;geschrieben&lt;/a&gt; hat) und &lt;a href="http://blog.sydoracle.com/2005/09/explain-plans-and-scalar-subqueries.html"&gt;Gary Myers&lt;/a&gt; verwiesen, die sich auch schon gelegentlich zum Thema geäußert haben.&lt;br /&gt;&lt;br /&gt;Ein Hinweis also, dass man scalar subqueries mit&amp;nbsp;Vorsicht zu verwenden hat - aber das sollte man ohnehin,&amp;nbsp;weil sie ab einer gewissen Größe der Ergebnismenge unheimlich kostspielig werden.&lt;br /&gt;&lt;br /&gt;Bei nochmaliger Durchsicht des Absatzes wird mir klar, dass ich mir nicht nur über den Einsatz von&amp;nbsp;scalar subqueries, sondern auch über den von Parenthesen Gedanken machen sollte.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-8397733608719214151?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/8397733608719214151/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2012/01/cost-fur-scalar-subqueries.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/8397733608719214151'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/8397733608719214151'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2012/01/cost-fur-scalar-subqueries.html' title='Cost für Scalar Subqueries'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-8212402000263153303</id><published>2012-01-18T08:43:00.000-08:00</published><updated>2012-01-18T08:43:02.369-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Index'/><title type='text'>Richard Foote über IOTs</title><content type='html'>Nachdem &lt;a href="http://mwidlake.wordpress.com/2011/07/18/index-organized-tables-the-basics/"&gt;Martin Widlake&lt;/a&gt; im vergangenen Jahr eine interessante Serie über &lt;i&gt;Index Organized Tables&lt;/i&gt; veröffentlichte, hat jetzt auch Richard Foote begonnen, das Thema genauer zu erläutern. Hier eine Liste der bisher veröffentlichten Artikel:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://richardfoote.wordpress.com/2012/01/10/index-organized-tables-an-introduction-of-sorts-pyramid-song/"&gt;Index Organized Tables – An Introduction Of Sorts (Pyramid Song)&lt;/a&gt;: zeigt - unter anderem anhand von Index Block Dumps - inwiefern eine IOT einem entsprechenden Index überlegen ist (soll heißen: kompakter ist), der alle für eine Query relevanten Spalten enthält (also einem "fat" oder "covering" index): der zentrale Unterschied liegt darin, dass in der IOT keine rowid gespeichert werden muss, da der Verweis auf das zugehörige Tabellensegment entfallen kann (da es kein solches Segment gibt).&lt;/li&gt;&lt;li&gt;&lt;a href="http://richardfoote.wordpress.com/2012/01/13/index-organized-tables-overflow-segment-shadow-man/"&gt;Index Organized Tables – Overflow Segment (Shadow Man)&lt;/a&gt;: erklärt den Sinn des Overflow-Segments, in das Spalten abgeschoben werden können, auf die eher selten zugegriffen wird. Solche Spalten würden die Index-Struktur unnötig aufblähen. Stattdessen kann man sie ins Overflow-Segment auslagern, das mehr oder minder einer Heap-Tabelle entspricht, aber nicht alle Spalten enthält (sondern nur die nutzlosen). Der erforderliche Pointer in der Index-Struktur nennt sich im Dump &lt;nrid&gt; "consisting of a 6 byte relative block address and row directory number". Während der Zugriff auf die Spalten im Index-Segment dadurch beschleunigt wird, erhöhen sich (natürlich) die Kosten für den Zugriff auf die ausgelagerten Spalten gegenüber einer entsprechenden IOT ohne Overflow-Segment.&lt;/nrid&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://richardfoote.wordpress.com/2012/01/18/index-organized-tables-overflow-segment-part-ii-the-loneliest-guy/"&gt;Index Organized Tables – Overflow Segment Part II (The Loneliest Guy)&lt;/a&gt;: hier erklärt Herr Foote, dass er&amp;nbsp;(wie vermutlich die meisten Leute)&amp;nbsp;PK-Spalten gerne an den Anfang der Spaltenliste einer Heap-Tabelle stellt, obwohl es durchaus auch Gründe dafür gäbe, sie nicht dort zu positionieren (da man ohnehin häufig über den PK zugreift und dann erst einmal über die bereits bekannten PK-Infos drüberlesen muss). Für IOTs ist die Platzierung der PK-Spalten an führende Stelle entscheidend. Tatsächlich ignoriert Oracle jede abweichende Definition und ordnet die PK-Spalten intern an den Anfang der Tabelle (was in der SEGMENT_COLUMN_ID in DBA_TAB_COLS abzulesen ist). Eine solche Umordnung kann dann unerfreuliche Wirkungen darauf haben, welche Spalten im Overflow-Segment landen, was man vor kurzem auch schon mal bei &lt;a href="http://jonathanlewis.wordpress.com/2011/12/11/iot-trap/"&gt;Jonathan Lewis&lt;/a&gt; lesen konnte.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Da es kaum jemanden gibt, der komplexe Sachverhalte in Oracle so klar darstellt wie der Herr Foote - und wahrscheinlich so gut wie niemanden, der sich mit Indizes besser auskennt -, lohnt es sich auf jeden Fall, die Artikel im Original zu lesen.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-8212402000263153303?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/8212402000263153303/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2012/01/richard-foote-uber-iots.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/8212402000263153303'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/8212402000263153303'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2012/01/richard-foote-uber-iots.html' title='Richard Foote über IOTs'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-8566488771479654311</id><published>2012-01-17T10:09:00.000-08:00</published><updated>2012-01-24T22:35:16.174-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Statistiken'/><title type='text'>Inkrementelle Statistiken</title><content type='html'>Randolf Geist beschäftigt sich in seinem &lt;a href="http://oracle-randolf.blogspot.com/2012/01/incremental-partition-statistics-review.html"&gt;Blog&lt;/a&gt; mit den Eigenschaften der in 11g eingeführten inkrementellen Partitions-Statistiken: "The most important point to understand is that Incremental Partition Statistics are not "cost-free", so anyone who is telling you that you can gather statistics on the lowest level (partition or sub-partition in case of composite partitioning) without any noticeable overhead in comparison to non-incremental statistics (on the lowest level) is not telling you the truth." Die angesprochenen Kosten liegen im Bereich der Laufzeiten und beim Speicherplatzbedarf in SYSAUX. Außerdem werden ein paar wichtige Detailbeobachtungen aufgeführt (z.B. wird bei Verwendung von INCREMENTAL die ESTIMATE_PERCENT-Angabe ignoriert).&lt;br /&gt;&lt;br /&gt;Ein paar (geringfügig) ältere Stellungnahmen zum Feature hatte ich vor kurzem &lt;a href="http://martinpreiss.blogspot.com/2011/11/statistik-erfassung-fur-groe.html"&gt;hier&lt;/a&gt; verlinkt.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Nachtrag 21.01.2011&lt;/b&gt;: Doug Burns, der dem Thema der Statistiken für Partitioned Tables im Jahr 2010 eine ganze &lt;a href="http://oracledoug.com/serendipity/index.php?/archives/1590-Statistics-on-Partitioned-Tables-Contents.html"&gt;Artikelserie&lt;/a&gt; gewidmet hat, gibt in seinem &lt;a href="http://oracledoug.com/serendipity/index.php?%2Farchives%2F1673-Randolf-Geist-on-11g-Incremental-Statistics.html"&gt;Blog&lt;/a&gt;&amp;nbsp;mit Bezug auf Randolfs Aussagen noch zwei Kommentare zu den inkremetellen Statistiken:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;dass Oracle beim initialen Aufbau von inkrementellen Statistiken die komplette Tabelle lesen muss, um die Synopsis aufzubauen, erscheint selbstverständlich: diese lange Laufzeit ist unvermeidbar&lt;/li&gt;&lt;li&gt;"Incrementals are a replacement for GRANULARITY=&amp;gt;'GLOBAL AND PARTITION' and not 'PARTITION'! Expecting an option which gathers Partition stats and then goes around updating synposes to perform as well as a simple partition gather is unrealistic*. Any performance improvement needs to be measured against both gathering the Partition stats and maintaining the Global stats. Incrementals will almost definitely be quicker than that!"&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Der Vollständigkeit halber noch der Hinweis, dass diese Aussagen keinen Widerspruch zu den Geist'schen Ausführungen darstellen.&lt;/div&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-8566488771479654311?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/8566488771479654311/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2012/01/inkrementelle-statistiken.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/8566488771479654311'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/8566488771479654311'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2012/01/inkrementelle-statistiken.html' title='Inkrementelle Statistiken'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-4471262455040778872</id><published>2012-01-11T05:12:00.000-08:00</published><updated>2012-01-11T05:12:57.568-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='DB-Link'/><title type='text'>Löschung eines verwendeten DB-Links</title><content type='html'>Was passiert, wenn man einen DB-Link löscht, der gerade in einer anderen Session verwendet wird? Die Antwort lautet: der Link wird gelöscht, ohne dass die zweite Session sich daran stört.&lt;br /&gt;&lt;br /&gt;&lt;div class="codesnippet"&gt;&lt;pre&gt;-- Session 1&lt;br /&gt;-- Anlage eines DB-Links &lt;br /&gt;-- (in diesem Fall ein loopback Link auf die gleiche Instanz,&lt;br /&gt;-- was aber wohl keine Rolle spielt)&lt;br /&gt;create database link loopback using 'TestDB';&lt;br /&gt;&lt;br /&gt;-- Session 2&lt;br /&gt;select count(*) from t_remote@loopback;&lt;br /&gt;&lt;br /&gt;-- Session 1&lt;br /&gt;drop database link loopback;&lt;br /&gt;&lt;br /&gt;-- Session 2&lt;br /&gt;--&gt; liefert das Ergebnis der Abfrage&lt;br /&gt;&lt;br /&gt;  COUNT(*)&lt;br /&gt;----------&lt;br /&gt;  24800000&lt;br /&gt;&lt;br /&gt;-- erneute Ausführung&lt;br /&gt;select count(*) from t_remote@loopback&lt;br /&gt;                              *&lt;br /&gt;FEHLER in Zeile 1:&lt;br /&gt;ORA-02019: Verbindungsbeschreibung für Fern-Datenbank nicht gefunden&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;Somit bleibt die Verbindung also für die Dauer der Query bestehen. Wenn ich darüber nachdenke, ist das Verhalten auch ganz plausibel: selbst die Löschung einer Tabelle führt ja nicht (notwendigerweise) zum Abbruch einer Query.&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-4471262455040778872?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/4471262455040778872/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2012/01/loschung-eines-verwendeten-db-links.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/4471262455040778872'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/4471262455040778872'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2012/01/loschung-eines-verwendeten-db-links.html' title='Löschung eines verwendeten DB-Links'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-835491682261326907</id><published>2012-01-06T05:22:00.000-08:00</published><updated>2012-01-08T12:54:55.972-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Trace'/><title type='text'>Index-Größenschätzung durch Explain Plan</title><content type='html'>Heute ist mir zum ersten Mal aufgefallen, dass Explain Plan für ein CREATE INDEX eine Größenschätzung liefert:&lt;br /&gt;&lt;br /&gt;&lt;div class="codesnippet"&gt;&lt;pre&gt;explain plan for&lt;br /&gt;create index idx_t1 on t1(a);&lt;br /&gt;&lt;br /&gt;select * from table(dbms_xplan.display);&lt;br /&gt;&lt;br /&gt;Plan hash value: 2186317495&lt;br /&gt;&lt;br /&gt;---------------------------------------------------------------------------------&lt;br /&gt;| Id  | Operation              | Name   | Rows  | Bytes | Cost (%CPU)| Time     |&lt;br /&gt;---------------------------------------------------------------------------------&lt;br /&gt;|   0 | CREATE INDEX STATEMENT |        |   257K|  3264K|  1001   (1)| 00:00:13 |&lt;br /&gt;|   1 |  INDEX BUILD NON UNIQUE| IDX_T1 |       |       |            |          |&lt;br /&gt;|   2 |   SORT CREATE INDEX    |        |   257K|  3264K|            |          |&lt;br /&gt;|   3 |    TABLE ACCESS FULL   | T1     |   257K|  3264K|   858   (1)| 00:00:11 |&lt;br /&gt;---------------------------------------------------------------------------------&lt;br /&gt;&lt;br /&gt;Note&lt;br /&gt;-----&lt;br /&gt;   - estimated index size: 7340K bytes&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;Bisher war ich nie auf die Idee gekommen, dass Explain Plan für einen Index interessant sein könnte. Der Versuch herauszufinden, seit wann diese Option existiert, hat mich dann mal wieder zu Randolf Geists Blog geführt, wo sich ein Artikel &lt;a href="http://oracle-randolf.blogspot.com/2009/02/explain-plan-on-ddls.html"&gt;EXPLAIN PLAN on DDLs&lt;/a&gt; findet, der diese und manch andere Frage beantwortet:&lt;br /&gt;&lt;blockquote&gt;Starting with Oracle 10.2 you'll get an indication of the size of the index based on the dictionary statistics in the "Notes" section, so the estimate is only as good as your statistics allow for, in addition above points apply regarding the accuracy of the estimate in case of null values or function-based indexes. The size estimate is obviously based on the average column length recorded in the statistics.&lt;/blockquote&gt;Insgesamt scheint die Aussagekraft der Schätzung allerdings recht beschränkt zu sein, da sie diverse relevant Punkte ignoriert (Anzahl NULLs, implizite Tablespace-Zuordnung, Kompression, FBI, keine Unterscheidung zwischen B*Tree und Bitmap), wie Randolf anhand praktischer Tests nachweist.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Nachtrag 08.01.2012&lt;/b&gt;: kaum schreibe ich darüber, da sehe ich, dass Jonathan Lewis gerade gezeigt hat, dass die Schätzung &lt;a href="http://jonathanlewis.wordpress.com/2012/01/04/index-size-bug/"&gt;einen recht massiven Bug&lt;/a&gt; enthält (zumindest bis inklusive 11.2.0.2)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-835491682261326907?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/835491682261326907/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2012/01/index-groenschatzung-durch-explain-plan.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/835491682261326907'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/835491682261326907'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2012/01/index-groenschatzung-durch-explain-plan.html' title='Index-Größenschätzung durch Explain Plan'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-1955203560287716317</id><published>2012-01-04T08:54:00.000-08:00</published><updated>2012-01-04T08:55:00.805-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Bücher'/><title type='text'>Oracle Core von Jonathan Lewis</title><content type='html'>Kurz nach Weihnachten hat mir Amazon das bei Apress erschienene Buch &lt;a href="http://www.amazon.com/Oracle-Core-Essential-Internals-Developers/dp/1430239549/ref=sr_1_1?ie=UTF8&amp;amp;qid=1325691064&amp;amp;sr=8-1"&gt;Oracle Core. Essential Internals for DBAs and Developers&lt;/a&gt;&amp;nbsp;von Jonathan Lewis zugeschickt. Bei Amazon gibt's dazu aktuell fünf Customer Reviews, die dem Buch jeweils fünf Sterne zusprechen - die erste und ausführlichste hat (natürlich) Charles Hooper geliefert (und man findet sie - natürlich - auch in seinem &lt;a href="http://hoopercharles.wordpress.com/2011/12/25/book-review-oracle-core-essential-internals-for-dbas-and-developers/"&gt;Blog&lt;/a&gt;). Wenn man berücksichtigt, dass ich hier vermutlich auf keinen anderen Blog so viele Links setze, wie auf das Lewis'sche &lt;a href="http://jonathanlewis.wordpress.com/all-postings/"&gt;Scratchpad&lt;/a&gt;&amp;nbsp;und dass ich kein anderes Buch so oft erwähne wie &lt;i&gt;&lt;a href="http://www.amazon.com/Cost-Based-Oracle-Fundamentals-Experts-Voice/dp/1590596366/ref=sr_1_2?s=books&amp;amp;ie=UTF8&amp;amp;qid=1325692026&amp;amp;sr=1-2"&gt;Cost-Based Oracle&lt;/a&gt;&lt;/i&gt;, überrascht's vermutlich nicht allzu sehr, dass ich jetzt in die allgemeinen Lobeshymnen einstimmen werde: der Herr Lewis hat da - zum dritten Mal (nach dem CBO-Buch und dem selbst heute noch relevanten &lt;i&gt;&lt;a href="http://www.amazon.com/Practical-Oracle8i-Building-Efficient-Databases/dp/0201715848/ref=sr_1_5?s=books&amp;amp;ie=UTF8&amp;amp;qid=1325692026&amp;amp;sr=1-5"&gt;Practical Oracle 8i&lt;/a&gt;&amp;nbsp;&lt;/i&gt;aus dem Jahr 2000) - ein grundlegendes Buch zum Verständnis des Oracle Servers vorgelegt. Tanel Poder, der offizielle Technical Reviewer des Bandes (was ein weiteres Qualitätssiegel wäre, wenn man noch eines brauchte), schreibt in seinem Amazon-Kommentar: "It will probably become THE technical source for Oracle internals information for the next 10 years, just like Steve Adams'es Oracle Internal Services book was in the previous decade." Und damit hat er vermutlich recht.&lt;br /&gt;&lt;br /&gt;Was der Herr Lewis in seinem Buch leistet, ist das, was Tom Kyte in &lt;i&gt;&lt;a href="http://www.amazon.com/Expert-Oracle-Database-Architecture-Programming/dp/1430229462/ref=sr_1_1?s=books&amp;amp;ie=UTF8&amp;amp;qid=1325692380&amp;amp;sr=1-1"&gt;Expert Oracle Database Architecture&lt;/a&gt;&lt;/i&gt; explizit verweigert: "Time and time again, I get questions regarding the exact bits and bytes of redo and undo. People seem to want to have a very detailed specification of exactly, precisly, what is in there. I never answer those questions." (S. 299) Der Herr Kyte hat dafür durchaus gute Gründe: er will die grundsätzlichen Konzepte erläutern und erklären, wozu redo und undo gedacht sind und wie sie zusammenarbeiten. Möglicherweise sieht er auch ähnliche Problem wie Tanel Poder, dessen (in &lt;i&gt;Oracle Core&lt;/i&gt; zitierte) Erklärung, warum er selbst kein Buch über Oracle Internals schreibe, lautet: "I think the subject just changes too fast." (S. XIV)&amp;nbsp;Dass Jonathan Lewis trotzdem ein Buch geschrieben hat, dessen Halbwertszeit - meiner Einschätzung nach - recht hoch sein wird, liegt daran, dass er in erster Linie über die grundlegendsten Mechanismen des Oracle Servers schreibt, und diese Mechanismen sind letztlich doch recht stabil. Vieles von dem, was man in Oracle Core findet, konnte man auch schon anderswo lesen: vor allem in den zahlreichen hochklassigen Blogs der Oracle-Community. Aber die konsistente Darstellung dieser Einzelbeobachtungen im Zusammenhang ist die große Leistung des Herrn Lewis, der meiner Meinung nach ohnehin einer der besten Stilisten unter den Oracle-Autoren ist.&lt;br /&gt;&lt;br /&gt;Es folgt eine kurze Zusammenfassung der Kapitel des relativ schmalen Bandes (266 Seiten), aber die wird hier als work-in-progress erst allmählich entstehen, weil mich die nachvollziehende Lektüre sehr viel Zeit kosten wird:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Kapitel 1&lt;/b&gt;: Getting Started: liefert auf vier Seiten eine ganz knappe Übersicht zu den Prozessen und Speicherstukturen in einer Oracle Instanz.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Kapitel 2&lt;/b&gt;: Redo and Undo: erläutert das Zusammenspiel von Redo und Undo bei einer Blockänderung: zu jeder Änderung werden eine redo-Information und eine undo-Information erzeugt, wobei auch für die undo-Information noch einmal eine redo-Information geschrieben werden muss. Erst dann kann die Änderung im data block erfolgen. Die Reihenfolge ist dabei:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;change vector für undo record erzeugen&lt;/li&gt;&lt;li&gt;change vector für data block erzeugen&lt;/li&gt;&lt;li&gt;change vektoren kombinieren und redo in den log buffer schreiben&lt;/li&gt;&lt;li&gt;undo record in den undo block schreiben&lt;/li&gt;&lt;li&gt;Änderung des data blocks durchführen&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;In älteren Releases wurde für jede Änderung einer Session ein redo record in den log buffer eingetragen, aber seit Oracle 10 werden mehrere Änderungen in einem privaten Speicherbereich (private strand) gesammelt und dann zusammengefasst gespeichert, was eine Reduzierung der erforderlichen Latches (redo copy, redo allocation) herbeiführt (allerdings kommen neue In memory undo Latches hinzu), die dadurch noch signifikanter wird, dass es mehrere child latches für die&amp;nbsp;In memory undo Latches&amp;nbsp;gibt, während die Latches für den zentralen Log Buffer notwenigerweise eine knappe Ressource waren.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Wie die folgenden Kapitel basiert auch dieses auf der detaillierten Auswertung von Block Dumps, die alle relevanten Informationen zu den Zusammenhängen enthalten - man muss sie nur interpretieren können ...&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-1955203560287716317?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/1955203560287716317/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2012/01/oracle-core-von-jonathan-lewis.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/1955203560287716317'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/1955203560287716317'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2012/01/oracle-core-von-jonathan-lewis.html' title='Oracle Core von Jonathan Lewis'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-1524190327469497144</id><published>2012-01-01T03:49:00.000-08:00</published><updated>2012-01-01T03:49:37.164-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Hardware'/><category scheme='http://www.blogger.com/atom/ns#' term='SSD'/><title type='text'>SSD für Oracle-Datenbanken</title><content type='html'>Bei &lt;a href="http://www.pythian.com/news/28797/de-confusing-ssd-for-oracle-databases/"&gt;Gwen Shapira&lt;/a&gt; findet man ein paar grundlegende Informationen zum Einsatz von SSDs in Oracle-Datenbanken - interessant sind dabei auch die zahlreichen Kommentare zum Artikel. Zu den wichtigsten Hinweisen gehören die Erläuterungen zur Performance bei Lese- und Schreiboperationen unterschiedlichen Typs. Ohne den Artikel komplett exzerpieren zu wollen hier ein paar der wichtigsten Punkte:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;SSD ist nur interessant, wenn die Hauptlast einer DB im I/O-Bereich liegt (was bei den meisten DBs, die ich sehe, der Fall ist).&lt;/li&gt;&lt;li&gt;wenn man es bezahlen kann, sollte man alle &lt;i&gt;data files&lt;/i&gt; auf SSD legen.&lt;/li&gt;&lt;li&gt;für die redo logs sind SSDs nicht geeignet, da sie bei sequentiellem Schreiben keine Vorteile gegenüber spinning disks haben.&lt;/li&gt;&lt;li&gt;man kann SSDs über die Option&lt;i&gt; Database Smart Flash Cache&lt;/i&gt; als sekundären Cache der SGA verwenden - dort können dann Blöcke zwischengespeichert werden, die aus dem &lt;i&gt;Buffer Cache&lt;/i&gt; heraus gefallen sind, was das erneute Laden natürlich beschleunigt.&lt;/li&gt;&lt;li&gt;Für Exadata sieht alles noch mal ganz anders aus, aber Exadata ist dieser Tage nicht mein Thema.&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-1524190327469497144?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/1524190327469497144/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2012/01/ssd-fur-oracle-datenbanken.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/1524190327469497144'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/1524190327469497144'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2012/01/ssd-fur-oracle-datenbanken.html' title='SSD für Oracle-Datenbanken'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-7688595865476954940</id><published>2012-01-01T03:00:00.000-08:00</published><updated>2012-01-22T09:01:12.145-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='CBO'/><title type='text'>CBO Verbesserungen in 11g</title><content type='html'>Christian Antognini hat die Powerpoint-Folien zu seiner Präsentation &lt;a href="http://antognini.ch/papers/OracleQueryOptimizer11g_20111212.pdf"&gt;Challenges and Chances of the 11g Query Optimizer&lt;/a&gt; auf seiner Webseite verfügbar gemacht - und liefert damit eine sehr kompakte Zusammenfassung der in Version 11 ergänzten Features des CBO und der Statistikerfassung. Hier ein paar der aufgeführten Punkte:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Indizes&lt;/li&gt;&lt;ul&gt;&lt;li&gt;invisible indexes&lt;/li&gt;&lt;li&gt;Verwendung von linguistic indexes bei LIKE&lt;/li&gt;&lt;li&gt;Statistik Historie bleibt nach Index Rebuild erhalten (erst in 11.2)&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;CBO&lt;/li&gt;&lt;ul&gt;&lt;li&gt;FULL OUTER JOIN wird intern nicht mehr durch&amp;nbsp;UNION ALL abgebildet&lt;/li&gt;&lt;li&gt;Join-Filter Pruning (ist mir noch nicht völlig klar)&lt;/li&gt;&lt;li&gt;Table Expansion: unterschiedliche Teile einer partitionierten Tabelle können über unterschiedliche Zugriffswege abgearbeitet werden (FTS + Index-Zugriff)&lt;/li&gt;&lt;li&gt;Join Factorization: ein für mehrere Teile eines UNION ALL gemeinsamer Zugriff kann heraus faktoriert und nur einmal ausgeführt werden (erst in 11.2)&lt;/li&gt;&lt;li&gt;OR Expansion funktioniert auch mit FBI&lt;/li&gt;&lt;li&gt;Join Elimination: ein überflüssiger Join kann vermieden werden, wenn entsprechende Constraints existieren&lt;/li&gt;&lt;li&gt;Subquery Unnesting: NOT IN und NOT EXISTS werden in Joins umgewandelt, mit denen der CBO besser zurecht kommt&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Statistiken&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Bugs für System Statistics beseitigt&lt;/li&gt;&lt;li&gt;Präferenzen für Objekt-Statistiken definierbar&lt;/li&gt;&lt;li&gt;Auto Sample Size funktioniert jetzt richtig&lt;/li&gt;&lt;li&gt;Pending Statistics: werden nicht unmittelbar nach der Anlage veröffentlicht&lt;/li&gt;&lt;li&gt;Incremental Statistics für partitionierte Tabellen (dazu gibt's &lt;a href="http://martinpreiss.blogspot.com/2012/01/inkrementelle-statistiken.html"&gt;hier&lt;/a&gt; ein paar weiterführende Anmerkungen)&lt;/li&gt;&lt;li&gt;Extended Statistics für Expressions und Spaltengruppen (in 11.2.0.2 kann man automatisch bestimmen lassen, für welche Spaltengruppen solche Korrelationsstatistiken angelegt werden sollten)&lt;/li&gt;&lt;li&gt;Funktionen zum Vergleich von Statistiken&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Plan Stabilität&lt;/li&gt;&lt;ul&gt;&lt;li&gt;cursor_sharing = similar ist deprecated; es wurde gelegentlich als Krücke für Applikationen, die keine Bindevariablen verwenden, vorgeschlagen&lt;/li&gt;&lt;li&gt;Einführung von SPM&lt;/li&gt;&lt;li&gt;Adaptive Cursor Sharing&lt;/li&gt;&lt;li&gt;&lt;a href="http://blogs.oracle.com/optimizer/entry/cardinality_feedback"&gt;Cardinality Feedback&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-7688595865476954940?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/7688595865476954940/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2012/01/cbo-verbesserungen-in-11g.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/7688595865476954940'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/7688595865476954940'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2012/01/cbo-verbesserungen-in-11g.html' title='CBO Verbesserungen in 11g'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-7492165915732475710</id><published>2011-12-30T06:10:00.000-08:00</published><updated>2011-12-30T06:10:47.100-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Hints'/><title type='text'>Kategorisierung von Hints</title><content type='html'>Bei &lt;a href="http://orastory.wordpress.com/2011/12/12/hints-of-acceptability/"&gt;Dom Brooks&lt;/a&gt; findet man den Versuch einer Taxonomie der unterschiedlichen Typen von Hints, also z.B.:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Optimizer-Mode&lt;/li&gt;&lt;li&gt;Direct-Path&lt;/li&gt;&lt;li&gt;Anpassungen von Cardinality-Schätzungen&lt;/li&gt;&lt;li&gt;Bug-Handhabung&lt;/li&gt;&lt;li&gt;Cursor-Sharing&lt;/li&gt;&lt;li&gt;Parallelisierung&lt;/li&gt;&lt;li&gt;Caching&lt;/li&gt;&lt;li&gt;...&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Eine Liste verfügbarer Hints liefert V$SQL_HINT.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-7492165915732475710?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/7492165915732475710/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2011/12/kategorisierung-von-hints.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/7492165915732475710'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/7492165915732475710'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2011/12/kategorisierung-von-hints.html' title='Kategorisierung von Hints'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-1358815358720125127</id><published>2011-12-23T03:51:00.000-08:00</published><updated>2011-12-23T09:06:27.762-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Trace'/><title type='text'>Ergänzungen zu display_cursor</title><content type='html'>&lt;a href="http://www.oracle-randolf.blogspot.com/2011/12/extended-displaycursor-with-rowsource.html"&gt;Randolf Geist&lt;/a&gt; hat ein hübsches Weihnachtsgeschenk abgeliefert: eine um eine Reihe sehr nützlicher Zusatzinformationen erweiterte Version zur selbst schon extrem nützlichen dbms_xplan.display_cursor-Routine. Das Script kombiniert einige Ideen, die Adrian Billington und Kyle Hailey gelegentlich geäußert haben, mit zusätzlichen Ergänzungen, und macht es deutlich einfacher, den Ablauf der Operationen im &lt;i&gt;execution plan&lt;/i&gt; korrekt zu deuten. Für besonders nützlich halte ich den TCF Graph zur Visualisierung von Fehleinschätzungen bei den Cardinalities und die klarere Verteilung der I/O-Operationen auf die Einzelschritte (in den %SELF-Spalten und in den Graphen). Eine schöne Alternative für alle, die keine Lizenz für das Real-Time SQL Monitoring besitzen - dafür aber einen breiten Monitor.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-1358815358720125127?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/1358815358720125127/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2011/12/erganzungen-zu-displaycursor.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/1358815358720125127'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/1358815358720125127'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2011/12/erganzungen-zu-displaycursor.html' title='Ergänzungen zu display_cursor'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-7952632841476634589</id><published>2011-12-22T04:42:00.000-08:00</published><updated>2011-12-25T02:13:44.558-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Cost'/><title type='text'>ix_sel_with_filters</title><content type='html'>In &lt;i&gt;Cost-Based Oracle&lt;/i&gt; erläutert Jonathan Lewis im vierten Kapitel die Grundlagen des Index Costing und verweist dabei auf die von Wolfgang Breitling im Jahr 2002 veröffentlichte Formel:&lt;br /&gt;&lt;blockquote class="tr_bq"&gt;cost = blevel &lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;+ ceiling(leaf_blocks + effective index selectivity) &lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;+ ceiling(clustering_factor * effective table selectivity)&lt;/blockquote&gt;Völlig unproblematisch sind in dieser Rechnung die Faktoren blevel, leaf_blocks und clustering_factor, die man z.B. in der View user_indexes findet. Die beiden anderen Elemente &lt;i&gt;effective index selectivity&lt;/i&gt; und &lt;i&gt;effective table selectivity&lt;/i&gt; werden im CBO-Buch ebenfalls erläutert, aber ich hatte mir bisher nie die Mühe gemacht, zu prüfen, ob ich diese Erklärungen tatsächlich verstanden hatte. Das soll hiermit geändert werden.&lt;br /&gt;&lt;br /&gt;Dabei scheint die&amp;nbsp;&lt;i&gt;effective index selectivity&amp;nbsp;&lt;/i&gt;auch noch recht harmlos zu sein: sie ergibt sich aus der Kombination der Selektivitäten der für den Zugriff verwendeten Index-Spalten. leaf_blocks *&amp;nbsp;effective index selectivity repräsentiert dabei die Kosten des Zugriffs auf die Index-Struktur, von der ein durch die&amp;nbsp;&lt;i&gt;effective index selectivity&lt;/i&gt; bestimmter Anteil gelesen werden muss.&lt;br /&gt;&lt;br /&gt;Zur&amp;nbsp;&lt;i&gt;effective table selectivity&lt;/i&gt; schreibt Jonathan Lewis, sie solle "be based only on those predicates that can be evaluated in the index, before you reach the table." (S. 67) Da mir dieser Punkt noch immer nicht völlig klar ist dazu ein kleiner Test (mit 11.2.0.1):&lt;br /&gt;&lt;br /&gt;&lt;div class="codesnippet"&gt;&lt;pre&gt;-- Anlage einer Test-Tabelle mit einem zusammengesetzten Index&lt;br /&gt;drop table test_ind_selectivity;&lt;br /&gt;&lt;br /&gt;create table test_ind_selectivity tablespace test_ts&lt;br /&gt;as&lt;br /&gt;select rownum id&lt;br /&gt;     , mod(rownum, 10) col1 -- 10 unterschiedliche Werte -&amp;gt; Selektivität: 0,1&lt;br /&gt;     , mod(rownum, 100) col2 -- 100 unterschiedliche Werte -&amp;gt; Selektivität: 0,01 &lt;br /&gt;     , mod(rownum, 1000) col3 -- 1000 unterschiedliche Werte -&amp;gt; Selektivität: 0,001  &lt;br /&gt;     , lpad('*', 100, '*') pad&lt;br /&gt;  from dual&lt;br /&gt;connect by level &amp;lt;= 1000000;&lt;br /&gt;&lt;br /&gt;exec dbms_stats.gather_table_stats(user, 'TEST_IND_SELECTIVITY', method_opt=&amp;gt;'FOR ALL COLUMNS SIZE 1')&lt;br /&gt;&lt;br /&gt;create index test_ind_selectivity_ix1 on test_ind_selectivity(col1, col2, col3);&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;Für den Index ergeben sich folgende Statistiken: &lt;br /&gt;&lt;div class="codesnippet"&gt;&lt;pre&gt;&lt;/pre&gt;&lt;pre&gt;select index_name&lt;br /&gt;     , blevel&lt;br /&gt;     , leaf_blocks&lt;br /&gt;     , clustering_factor&lt;br /&gt;  from user_indexes&lt;br /&gt; where table_name = upper('test_ind_selectivity');&lt;br /&gt;&lt;br /&gt;INDEX_NAME                         BLEVEL LEAF_BLOCKS CLUSTERING_FACTOR&lt;br /&gt;------------------------------ ---------- ----------- -----------------&lt;br /&gt;TEST_IND_SELECTIVITY_IX1                2        2894           1000000&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;Ich könnte jetzt die tatsächlichen Kosten von Queries ermitteln und versuchen, passende Werte für die Selektivitäten einzusetzen, aber ich mache mir die Sache ganz einfach und erzeuge ein 10053er Trace:  &lt;br /&gt;&lt;br /&gt;&lt;div class="codesnippet"&gt;&lt;pre&gt;&lt;/pre&gt;&lt;pre&gt;ALTER SESSION SET EVENTS '10053 trace name context forever, level 1';&lt;br /&gt;&lt;br /&gt;select /*+ index(test_ind_selectivity) test1 */ count(id) from test_ind_selectivity where col1 = 1;&lt;br /&gt;&lt;br /&gt;select /*+ index(test_ind_selectivity) test2 */ count(id) from test_ind_selectivity where col1 = 1 and col2 = 1;&lt;br /&gt;&lt;br /&gt;select /*+ index(test_ind_selectivity) test3 */ count(id) from test_ind_selectivity where col1 = 1 and col2 = 1 and col3 = 1;&lt;br /&gt;&lt;br /&gt;select /*+ index(test_ind_selectivity) test4 */ count(id) from test_ind_selectivity where col1 = 1 and col3 = 1;&lt;br /&gt;&lt;br /&gt;ALTER SESSION SET EVENTS '10053 trace name context OFF';&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;Für die Queries ergeben sich folgende Trace-Inhalte:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Fall 1: where col1 = 1&lt;/b&gt; &lt;br /&gt;&lt;div class="codesnippet"&gt;&lt;pre&gt;***************************************&lt;br /&gt;BASE STATISTICAL INFORMATION&lt;br /&gt;***********************&lt;br /&gt;Table Stats::&lt;br /&gt;  Table: TEST_IND_SELECTIVITY  Alias: TEST_IND_SELECTIVITY&lt;br /&gt;    #Rows: 1000000  #Blks:  16907  AvgRowLen:  116.00&lt;br /&gt;Index Stats::&lt;br /&gt;  Index: TEST_IND_SELECTIVITY_IX1  Col#: 2 3 4&lt;br /&gt;    LVLS: 2  #LB: 2894  #DK: 1000  LB/K: 2.00  DB/K: 1000.00  CLUF: 1000000.00&lt;br /&gt;    User hint to use this index&lt;br /&gt;Access path analysis for TEST_IND_SELECTIVITY&lt;br /&gt;***************************************&lt;br /&gt;SINGLE TABLE ACCESS PATH &lt;br /&gt;  Single Table Cardinality Estimation for TEST_IND_SELECTIVITY[TEST_IND_SELECTIVITY] &lt;br /&gt;  Table: TEST_IND_SELECTIVITY  Alias: TEST_IND_SELECTIVITY&lt;br /&gt;    Card: Original: 1000000.000000  Rounded: 100000  Computed: 100000.00  Non Adjusted: 100000.00&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;  Access Path: index (RangeScan)&lt;br /&gt;    Index: TEST_IND_SELECTIVITY_IX1&lt;br /&gt;    resc_io: 100292.00  resc_cpu: 751223460&lt;br /&gt;    ix_sel: 0.100000  ix_sel_with_filters: 0.100000 &lt;br /&gt;    Cost: 100292.15  Resp: 100292.15  Degree: 1&lt;br /&gt;  Best:: AccessPath: IndexRange&lt;br /&gt;  Index: TEST_IND_SELECTIVITY_IX1&lt;br /&gt;         Cost: 100292.15  Degree: 1  Resp: 100292.15  Card: 100000.00  Bytes: 0&lt;br /&gt;&lt;br /&gt;***************************************&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;Die ix_sel repräsentiert im 10053er Trace die effective index selectivity, während die ix_sel_with_filters für die effective table selectivity steht. Beide Werte sind für die erste Query 0,1 - und entsprechen damit der Selektivität der Einzel-Spalte. Setzt man die Werte in die Formel ein, ergibt sich:   &lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;blevel + ceiling(leaf_blocks + effective index selectivity) + ceiling(clustering_factor * effective table selectivity)&lt;/li&gt;&lt;li&gt;2 + ceil(2894 * 0,1) + ceil(1000000 * 0,1)&lt;/li&gt;&lt;li&gt;2 + 290 + 100000 = 100292&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Das passt dann schon mal zur resc_io, die offenbar den I/O-Anteil der Kosten darstellt. Die zusätzlichen 0,15 in den Kosten sind dann vermutlich der CPU-Anteil.&lt;/div&gt;&lt;br /&gt;&lt;b&gt;Fall 2: where col1 = 1 and col2 = 1&lt;/b&gt; &lt;br /&gt;&lt;div class="codesnippet"&gt;&lt;pre&gt;***************************************&lt;br /&gt;BASE STATISTICAL INFORMATION&lt;br /&gt;***********************&lt;br /&gt;Table Stats::&lt;br /&gt;  Table: TEST_IND_SELECTIVITY  Alias: TEST_IND_SELECTIVITY&lt;br /&gt;    #Rows: 1000000  #Blks:  16907  AvgRowLen:  116.00&lt;br /&gt;Index Stats::&lt;br /&gt;  Index: TEST_IND_SELECTIVITY_IX1  Col#: 2 3 4&lt;br /&gt;    LVLS: 2  #LB: 2894  #DK: 1000  LB/K: 2.00  DB/K: 1000.00  CLUF: 1000000.00&lt;br /&gt;    User hint to use this index&lt;br /&gt;Access path analysis for TEST_IND_SELECTIVITY&lt;br /&gt;***************************************&lt;br /&gt;SINGLE TABLE ACCESS PATH &lt;br /&gt;  Single Table Cardinality Estimation for TEST_IND_SELECTIVITY[TEST_IND_SELECTIVITY] &lt;br /&gt;  ColGroup (#1, Index) TEST_IND_SELECTIVITY_IX1&lt;br /&gt;    Col#: 2 3 4    CorStregth: -1.00&lt;br /&gt;  ColGroup Usage:: PredCnt: 2  Matches Full:  Partial: &lt;br /&gt;  Table: TEST_IND_SELECTIVITY  Alias: TEST_IND_SELECTIVITY&lt;br /&gt;    Card: Original: 1000000.000000  Rounded: 1000  Computed: 1000.00  Non Adjusted: 1000.00&lt;br /&gt;  ColGroup Usage:: PredCnt: 2  Matches Full:  Partial: &lt;br /&gt;  ColGroup Usage:: PredCnt: 2  Matches Full:  Partial: &lt;br /&gt;  Access Path: index (RangeScan)&lt;br /&gt;    Index: TEST_IND_SELECTIVITY_IX1&lt;br /&gt;    resc_io: 1005.00  resc_cpu: 7547047&lt;br /&gt;    ix_sel: 0.001000  ix_sel_with_filters: 0.001000 &lt;br /&gt;    Cost: 1005.00  Resp: 1005.00  Degree: 1&lt;br /&gt;  Best:: AccessPath: IndexRange&lt;br /&gt;  Index: TEST_IND_SELECTIVITY_IX1&lt;br /&gt;         Cost: 1005.00  Degree: 1  Resp: 1005.00  Card: 1000.00  Bytes: 0&lt;br /&gt;&lt;br /&gt;***************************************&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;In diesem Fall sind beide Selektivitäten auf 0,001 (also das Produkt der Selektivitäten der Einzelspalten 0,1 * 0,01) gesetzt, was auch wieder den Erwartungen entspricht. In der Formel ergibt sich für die Komponenten 2 + 3 + 1000.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Fall 3: where col1 = 1 and col2 = 1 and col3 = 1&lt;/b&gt; &lt;br /&gt;&lt;div class="codesnippet"&gt;&lt;pre&gt;***************************************&lt;br /&gt;BASE STATISTICAL INFORMATION&lt;br /&gt;***********************&lt;br /&gt;Table Stats::&lt;br /&gt;  Table: TEST_IND_SELECTIVITY  Alias: TEST_IND_SELECTIVITY&lt;br /&gt;    #Rows: 1000000  #Blks:  16907  AvgRowLen:  116.00&lt;br /&gt;Index Stats::&lt;br /&gt;  Index: TEST_IND_SELECTIVITY_IX1  Col#: 2 3 4&lt;br /&gt;    LVLS: 2  #LB: 2894  #DK: 1000  LB/K: 2.00  DB/K: 1000.00  CLUF: 1000000.00&lt;br /&gt;    User hint to use this index&lt;br /&gt;Access path analysis for TEST_IND_SELECTIVITY&lt;br /&gt;***************************************&lt;br /&gt;SINGLE TABLE ACCESS PATH &lt;br /&gt;  Single Table Cardinality Estimation for TEST_IND_SELECTIVITY[TEST_IND_SELECTIVITY] &lt;br /&gt;  ColGroup (#1, Index) TEST_IND_SELECTIVITY_IX1&lt;br /&gt;    Col#: 2 3 4    CorStregth: 1000.00&lt;br /&gt;  ColGroup Usage:: PredCnt: 3  Matches Full: #1  Partial:  Sel: 0.0010&lt;br /&gt;  Table: TEST_IND_SELECTIVITY  Alias: TEST_IND_SELECTIVITY&lt;br /&gt;    Card: Original: 1000000.000000  Rounded: 1000  Computed: 1000.00  Non Adjusted: 1000.00&lt;br /&gt;  ColGroup Usage:: PredCnt: 3  Matches Full: #1  Partial:  Sel: 0.0010&lt;br /&gt;  ColGroup Usage:: PredCnt: 3  Matches Full: #1  Partial:  Sel: 0.0010&lt;br /&gt;  Access Path: index (AllEqRange)&lt;br /&gt;    Index: TEST_IND_SELECTIVITY_IX1&lt;br /&gt;    resc_io: 1005.00  resc_cpu: 7567047&lt;br /&gt;    ix_sel: 0.001000  ix_sel_with_filters: 0.001000 &lt;br /&gt;    Cost: 1005.00  Resp: 1005.00  Degree: 1&lt;br /&gt;  Best:: AccessPath: IndexRange&lt;br /&gt;  Index: TEST_IND_SELECTIVITY_IX1&lt;br /&gt;         Cost: 1005.00  Degree: 1  Resp: 1005.00  Card: 1000.00  Bytes: 0&lt;br /&gt;&lt;br /&gt;***************************************&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;Die Werte für ix_sel und ix_sel_with_filters sind mit denen in Fall 2 identisch. Ein offensichtlicher Unterschied sind die Angaben unter Partial und CorStregth (wo vielleicht ein n fehlt) - zu diesen Einträgen im CBO-Trace hat Randolf Geist im Rahmen einer &lt;a href="http://oracle-randolf.blogspot.com/2009/01/correlation-nocorrelation-and-extended.html"&gt;Untersuchung von Korrelationseffekten und extended statistics&lt;/a&gt; (die wiederum auf einen Artikel von Riyaj Shamsudeen Bezug nimmt) gelegentlich ein paar Erläuterungen gegeben, die ich so interpretiere, dass die Angaben etwas über die Korrelation der Spaltenwerte aussagen und durch extended statistics und Histogramme beeinflusst werden können. Die Werte in Fall 3 scheinen anzudeuten, dass der CBO die Korrelation der Spalten erkennt, aber wie er das macht, ist mir unklar, da keine extended statistics erzeugt wurden (und auch keine Histogramme: method_opt=&amp;gt;'FOR ALL COLUMNS SIZE 1'). In jedem Fall entsprechen die Kosten exakt denen von Fall 2.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Nachtrag 24.12.2011&lt;/b&gt;: Die Antwort auf meine Frage liefert Randolf Geists Kommentar: im gegebenen Fall eines Zugriffs mit Einschränkung auf alle Index-Spalten kann der CBO die Index-Statistiken verwenden, statt sich mit der indirekten Bestimmung über die Tabellenspalten-Statistiken behelfen zu müssen.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Fall 4: where col1 = 1 and col3 = 1&lt;/b&gt; &lt;br /&gt;&lt;div class="codesnippet"&gt;&lt;pre&gt;***************************************&lt;br /&gt;BASE STATISTICAL INFORMATION&lt;br /&gt;***********************&lt;br /&gt;Table Stats::&lt;br /&gt;  Table: TEST_IND_SELECTIVITY  Alias: TEST_IND_SELECTIVITY&lt;br /&gt;    #Rows: 1000000  #Blks:  16907  AvgRowLen:  116.00&lt;br /&gt;Index Stats::&lt;br /&gt;  Index: TEST_IND_SELECTIVITY_IX1  Col#: 2 3 4&lt;br /&gt;    LVLS: 2  #LB: 2894  #DK: 1000  LB/K: 2.00  DB/K: 1000.00  CLUF: 1000000.00&lt;br /&gt;    User hint to use this index&lt;br /&gt;Access path analysis for TEST_IND_SELECTIVITY&lt;br /&gt;***************************************&lt;br /&gt;SINGLE TABLE ACCESS PATH &lt;br /&gt;  Single Table Cardinality Estimation for TEST_IND_SELECTIVITY[TEST_IND_SELECTIVITY] &lt;br /&gt;  ColGroup (#1, Index) TEST_IND_SELECTIVITY_IX1&lt;br /&gt;    Col#: 2 3 4    CorStregth: -1.00&lt;br /&gt;  ColGroup Usage:: PredCnt: 2  Matches Full:  Partial: #1 (2 4 )  Sel: 0.0010&lt;br /&gt;  Table: TEST_IND_SELECTIVITY  Alias: TEST_IND_SELECTIVITY&lt;br /&gt;    Card: Original: 1000000.000000  Rounded: 1000  Computed: 1000.00  Non Adjusted: 1000.00&lt;br /&gt;kkofmx: index filter:"TEST_IND_SELECTIVITY"."COL3"=1&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;  ColGroup Usage:: PredCnt: 2  Matches Full:  Partial: #1 (2 4 )  Sel: 0.0010&lt;br /&gt;  ColGroup Usage:: PredCnt: 2  Matches Full:  Partial: #1 (2 4 )  Sel: 0.0010&lt;br /&gt;  Access Path: index (skip-scan)&lt;br /&gt;    SS sel: 0.001000  ANDV (#skips): 100.000000&lt;br /&gt;    SS io: 300.000000 vs. index scan io: 8455.000000&lt;br /&gt;    Skip Scan rejected&lt;br /&gt;  Access Path: index (RangeScan)&lt;br /&gt;    Index: TEST_IND_SELECTIVITY_IX1&lt;br /&gt;    resc_io: 1292.00  resc_cpu: 29410900&lt;br /&gt;    ix_sel: 0.100000  ix_sel_with_filters: 0.001000 &lt;br /&gt; ***** Logdef predicate Adjustment ****** &lt;br /&gt; Final IO cst 0.00 , CPU cst 50.00&lt;br /&gt; ***** End Logdef Adjustment ****** &lt;br /&gt;    Cost: 1292.01  Resp: 1292.01  Degree: 1&lt;br /&gt;  Best:: AccessPath: IndexRange&lt;br /&gt;  Index: TEST_IND_SELECTIVITY_IX1&lt;br /&gt;         Cost: 1292.01  Degree: 1  Resp: 1292.01  Card: 1000.00  Bytes: 0&lt;br /&gt;&lt;br /&gt;***************************************&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;In diesem Fall erscheinen nur die führende und die letzte Spalte des Index in der WHERE-Bedingung. Einleuchtend ist deshalb die&amp;nbsp;ix_sel, die nur die Selektivität der führenden Spalte berücksichtigt: aufgrund der Einschränkung müssen 10% der Index-Struktur durchsucht werden, um alle Sätze mit col1 = 1 zu ermitteln, ehe dann die Filterung auf col3 = 1 erfolgen kann. Aber die&amp;nbsp;ix_sel_with_filters ist mir nicht ganz klar, denn sie ergibt sich nicht aus der Selektivität der beiden Spalten (0,1 * 0,001 wären 0,0001). Möglicherweise ist auch hier eine Korrelationsbestimmung im Spiel, denn die&amp;nbsp;ix_sel_with_filters =&amp;nbsp;0.001000 entspricht der Angabe in: &amp;nbsp;Partial: #1 (2 4 )  Sel: 0.0010. Auch in diesem Fall ist mir unklar, wie der CBO die Korrelation erkennen kann.&lt;br /&gt;&lt;br /&gt;Interessant ist darüber hinaus noch der Plan für die vierte Query, der sich im CBO-Trace ebenfalls findet:&lt;br /&gt;&lt;div class="codesnippet"&gt;&lt;pre&gt;============&lt;br /&gt;Plan Table&lt;br /&gt;============&lt;br /&gt;----------------------------------------------------------------+-----------------------------------+&lt;br /&gt;| Id  | Operation                     | Name                    | Rows  | Bytes | Cost  | Time      |&lt;br /&gt;----------------------------------------------------------------+-----------------------------------+&lt;br /&gt;| 0   | SELECT STATEMENT              |                         |       |       |  1292 |           |&lt;br /&gt;| 1   |  SORT AGGREGATE               |                         |     1 |    12 |       |           |&lt;br /&gt;| 2   |   TABLE ACCESS BY INDEX ROWID | TEST_IND_SELECTIVITY    |  1000 |   12K |  1292 |  00:00:07 |&lt;br /&gt;| 3   |    INDEX RANGE SCAN           | TEST_IND_SELECTIVITY_IX1|  1000 |       |   292 |  00:00:02 |&lt;br /&gt;----------------------------------------------------------------+-----------------------------------+&lt;br /&gt;Predicate Information:&lt;br /&gt;----------------------&lt;br /&gt;3 - access("COL1"=1 AND "COL3"=1)&lt;br /&gt;3 - filter("COL3"=1)&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;Hier erscheinen col1 und col3 als access-Prädikate und col3 dann noch einmal als Filter-Prädikat. Ich hatte erwartet, dass nur col1 als access-Prädikat verwendbar wäre und deshalb 100000 Sätze über den Index gelesen werden müssten, ehe die zusätzliche Filterung auf col3 = 1 erfolgen könnte, aber das ist offenbar nicht der Fall, wie die Ausführungsinformationen belegen:&lt;br /&gt;&lt;br /&gt;&lt;div class="codesnippet"&gt;&lt;pre&gt;select plan_table_output&lt;br /&gt;  from table( dbms_xplan.display_cursor ( NULL, NULL, 'allstats'));&lt;br /&gt;&lt;br /&gt;PLAN_TABLE_OUTPUT&lt;br /&gt;--------------------------------------------------------------------------------------------------------------------&lt;br /&gt;SQL_ID  gj6fuawjzpr51, child number 0&lt;br /&gt;-------------------------------------&lt;br /&gt;select /*+ index(test_ind_selectivity) gather_plan_statistics */&lt;br /&gt;count(id) from test_ind_selectivity where col1 = 1 and col3 = 1&lt;br /&gt;&lt;br /&gt;Plan hash value: 779399104&lt;br /&gt;&lt;br /&gt;-------------------------------------------------------------------------------------------------------------------&lt;br /&gt;| Id  | Operation                    | Name                     | Starts | E-Rows | A-Rows |   A-Time   | Buffers |&lt;br /&gt;-------------------------------------------------------------------------------------------------------------------&lt;br /&gt;|   0 | SELECT STATEMENT             |                          |      1 |        |      1 |00:00:00.03 |    1296 |&lt;br /&gt;|   1 |  SORT AGGREGATE              |                          |      1 |      1 |      1 |00:00:00.03 |    1296 |&lt;br /&gt;|   2 |   TABLE ACCESS BY INDEX ROWID| TEST_IND_SELECTIVITY     |      1 |   1000 |   1000 |00:00:00.01 |    1296 |&lt;br /&gt;|*  3 |    INDEX RANGE SCAN          | TEST_IND_SELECTIVITY_IX1 |      1 |   1000 |   1000 |00:00:00.01 |     296 |&lt;br /&gt;-------------------------------------------------------------------------------------------------------------------&lt;br /&gt;&lt;br /&gt;Predicate Information (identified by operation id):&lt;br /&gt;---------------------------------------------------&lt;br /&gt;&lt;br /&gt;   3 - access("COL1"=1 AND "COL3"=1)&lt;br /&gt;       filter("COL3"=1)&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;Tatsächlich liefert der Index-Zugriff also nur die 1000 relevanten Sätze, kann also die fehlende Spalte col2 überspringen - was durchaus plausibel ist, aber nicht unbedingt das, was ich erwartet hatte.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Nachtrag 24.12.2011&lt;/b&gt;: auch dazu liefert Randolf Geist in seinem Kommentar die Erklärung: der ACCESS liefert 296 von 1296 Blocks (und 100.000 Sätze) und anschließend erfolgt die FILTERung auf 1.000 Sätze. Das Erscheinen von col3 als ACCESS-Prädikat dient dabei offenbar nur zur Verwirrung... Hilfreich wär's, wenn die Informationen zum ACCESS auch noch bei den A-Rows auftauchen würden, wie Randolf unten anmerkt. Eine schöne Erklärung zur Interpretation von FILTER-Prädikaten in Index-Scan-Steps (und überhaupt zur Rolle von ACCESS- und FILTER-Prädikaten) findet man &lt;a href="http://use-the-index-luke.com/sql/explain-plan/oracle/filter-predicates"&gt;hier&lt;/a&gt; und &lt;a href="http://use-the-index-luke.com/sql/where-clause/searching-for-ranges/greater-less-between-tuning-sql-access-filter-predicates"&gt;hier&lt;/a&gt; bei Markus Winand.&lt;br /&gt;&lt;br /&gt;Einmal mehr bin ich nicht unbedingt dort angelangt, wo ich hin wollte - nämlich bei einem klaren Verständnis der ix_sel_with_filters, aber für heute genügt's mir.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-7952632841476634589?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/7952632841476634589/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2011/12/ixselwithfilters.html#comment-form' title='2 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/7952632841476634589'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/7952632841476634589'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2011/12/ixselwithfilters.html' title='ix_sel_with_filters'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-441714033132711493</id><published>2011-12-20T07:30:00.000-08:00</published><updated>2011-12-20T07:30:58.936-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Cost'/><category scheme='http://www.blogger.com/atom/ns#' term='CBO'/><title type='text'>RBO-Nutzung in Version 11</title><content type='html'>Maria Colgan erläutert im &lt;a href="http://blogs.oracle.com/optimizer/entry/why_was_the_rule_hint"&gt;Blog der CBO-Entwickler&lt;/a&gt;, welche Objekt- bzw. Query-Eigenschaften die Verwendung des CBO erzwingen. Grundsätzlich gilt, dass alle Features neueren Datums dazu führen, dass der RBO aus dem Spiel ist.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-441714033132711493?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/441714033132711493/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2011/12/rbo-nutzung-in-version-11.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/441714033132711493'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/441714033132711493'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2011/12/rbo-nutzung-in-version-11.html' title='RBO-Nutzung in Version 11'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-3651879202640042257</id><published>2011-12-14T02:44:00.000-08:00</published><updated>2012-01-28T05:04:05.187-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Trigger'/><title type='text'>Ehrenrettung für Trigger</title><content type='html'>Ich bin bei Tom Kyte (und anderswo) so oft vor dem Einsatz von Triggern gewarnt worden und habe selbst so viele Unerfreuliches mit ihnen erlebt, dass ich sehr gespannt darauf bin, was Toon Koppelaars in seinem neuen Blog &lt;a href="http://harmfultriggers.blogspot.com/"&gt;Triggers Considered Harmful, Considered Harmful&lt;/a&gt; alles aufführen wird, um den schlechten Ruf dieses Features zu korrigieren.&lt;br /&gt;&lt;br /&gt;Hier eine kurze Liste der bisher veröffentlichten Artikel (die ich vermutlich nicht bis zum Ende des Blogs ergänzen werde):&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://harmfultriggers.blogspot.com/2011/11/triggers-considered-harmful-considered.html"&gt;Starting this blog&lt;/a&gt;: mit einem Blick zurück ins Jahr 1994 und einigen Tom-Kyte-Zitaten zum Thema Trigger.&lt;/li&gt;&lt;li&gt;&lt;a href="http://harmfultriggers.blogspot.com/2011/11/so-what-triggers-are-we-talking-about.html"&gt;So what triggers are we talking about?&lt;/a&gt; mit einer kurzen Klassifizierung nach Trigger-Typen und einer Erläuterung zu row-level- und statement-level-triggers.&lt;/li&gt;&lt;li&gt;&lt;a href="http://harmfultriggers.blogspot.com/2011/11/some-preliminaries.html"&gt;Some preliminaries&lt;/a&gt;: erklärt, dass in einem Trigger keine DDL-Operation aufgerufen werden darf (wegen des impliziten Commit; wenn man den problematischen Code in eine autonome Transaktion packt, kann diese die Änderungen der laufenden DML-Operation dann - natürlich - nicht sehen). Dann wird erklärt, dass der Fehlschlag eines Triggers ein Statement-Rollback für die betroffene DML-Operation hervorruft.Außerdem wird das mutating table Problem erläutert: "row level triggers are not allowed to read what's called the mutating table. If your row level trigger code queries the table that's being affected by the triggering DML statement, then Oracle will throw an ORA-04091 at you and cause the above mentioned statement level rollback."&lt;/li&gt;&lt;li&gt;&lt;a href="http://harmfultriggers.blogspot.com/2011/11/workarounds-for-ora-04091.html"&gt;"Workarounds" for ORA-04091&lt;/a&gt;: nennt zwei beliebte Workarounds für das Mutating-Table-Problem: die Verwendung einer autonomen Transaktion und die (weit weniger verbreitete) Verwendung eines loopback db-link. Ein wichtiger Unterschied der beiden Varianten ist, dass der db-link-Zugriff die Änderungen der noch nicht festgeschriebenen Transaktion sehen kann (da er zur gleichen dirstibuted transaction gehört), während die autonomous transaction das (natürlich) nicht kann.&lt;/li&gt;&lt;li&gt;&lt;a href="http://harmfultriggers.blogspot.com/2011/12/mutating-table-error-prevents-non.html"&gt;The mutating table error prevents non-deterministic behavior of your code&lt;/a&gt;: erklärt, warum die beiden oben angeführten Workarounds grundsätzlich problematisch sind - und wieso der Mutating-Table-Error eine sinnvolle Sicherheitseinrichtung ist: im Fall des Inserts mehrerer Sätze entscheidet die Reihenfolge der rows darüber, ob ein row Trigger mit loopback db_link, der die Beziehung von Tabelleninhalten überprüft, einen Fehler liefert oder nicht - das Verhalten ist also nicht deterministisch. Ein row Trigger mit dem Pragma autonomous transaction würde in einem solchen Fall immer einen Fehler liefern, wenn die neu eingefügten Sätze nur in ihrer Kombination die Logik des Triggers erfüllen.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://harmfultriggers.blogspot.com/2011/12/look-mom-mutating-table-error-without.html"&gt;Look mom: a mutating table error without a trigger!&lt;/a&gt;: zeigt dass ORA-04091 nicht nur für Trigger relevant ist, sondern auch für Funktionen - und auch dort einen wichtigen Sicherheitsmechanismus darstellt..&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-3651879202640042257?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/3651879202640042257/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2011/12/ehrenrettung-fur-trigger.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/3651879202640042257'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/3651879202640042257'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2011/12/ehrenrettung-fur-trigger.html' title='Ehrenrettung für Trigger'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-8285851693451818888</id><published>2011-12-09T08:43:00.001-08:00</published><updated>2011-12-09T08:44:34.861-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='RAC'/><title type='text'>RAC-Test-Installation mit Oracle VM</title><content type='html'>Sollte ich mal wieder auf die seltsame Idee kommen, zu Test-Zwecken ein RAC-System aufzubauen, würde ich am besten noch mal einen Blick auf &lt;a href="http://gavinsoorma.com/2011/11/3366/"&gt;Gavin Soormas detaillierte Anleitung&lt;/a&gt; werfen.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-8285851693451818888?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/8285851693451818888/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2011/12/rac-test-installation-mit-oracle-vm.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/8285851693451818888'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/8285851693451818888'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2011/12/rac-test-installation-mit-oracle-vm.html' title='RAC-Test-Installation mit Oracle VM'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-6669845794021133031</id><published>2011-12-09T05:37:00.001-08:00</published><updated>2011-12-09T05:40:05.619-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Data Warehouse'/><title type='text'>Eine kurze Geschichte der Datenverarbeitung</title><content type='html'>Thomas Kejser hat in seinem &lt;a href="http://blog.kejser.org/2011/12/08/dont-become-a-one-trick-architect/"&gt;Blog&lt;/a&gt; eine kleine Geschichte der Datenverarbeitung in den letzten 40 Jahren aufgeschrieben. Der Historiker in mir freut sich über solche Überblicke.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-6669845794021133031?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/6669845794021133031/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2011/12/eine-kurze-geschichte-der.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/6669845794021133031'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/6669845794021133031'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2011/12/eine-kurze-geschichte-der.html' title='Eine kurze Geschichte der Datenverarbeitung'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-3026077580945526503</id><published>2011-12-08T12:32:00.001-08:00</published><updated>2012-02-15T02:45:11.626-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Pipelined Functions'/><category scheme='http://www.blogger.com/atom/ns#' term='PL/SQL'/><category scheme='http://www.blogger.com/atom/ns#' term='Cost'/><title type='text'>Join-Cardinality</title><content type='html'>Randolf Geist hat eine interessante Erläuterung zum Thema &lt;a href="http://oracle-randolf.blogspot.com/2011/12/table-functions-and-join-cardinality.html"&gt;Table Functions And Join Cardinality Estimates&lt;/a&gt; veröffentlicht. Zunächst erklärt er darin (unter Ausklammerung von Spezialeffekten mit NULL, Histogrammen etc.), wie der CBO die Cardinality eines Joins grundsätzlich einschätzt:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Join Selectivity = 1 / greater(num_distinct(t1.c1), num_distinct(t2.c2))&lt;/li&gt;&lt;li&gt;low and high values of the join columns: If the join columns do not overlap at all the join cardinality will be calculated as 1.&lt;/li&gt;&lt;li&gt;Finally this join selectivity will be multiplied by the (filtered) cardinality of the two row sources to arrive at the join cardinality: Join Cardinality = Join Selectivity * cardinality t1 * cardinality t2&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Dazu gibt's dann (natürlich) allerlei Beispiele. Im Hauptteil des Artikels erläutert der Herr Geist dann, warum der CBO im Fall von Table Functions auch bei Verwendung von dynamic sampling nicht zu den erwarteten Angaben kommt, aber diesen Teil des Artikels sollte man lieber im Original lesen, so dass ich mir hier das Exzerpieren spare.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Nachtrag 15.02.2012&lt;/b&gt;: im Sinne einer doppelt verketteten Liste hier noch der Verweis auf einen &lt;a href="http://martinpreiss.blogspot.com/2011/05/join-cardinality.html"&gt;älteren Eintrag&lt;/a&gt; zum gleichen Thema (und mit nahezu gleichem Titel).&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-3026077580945526503?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/3026077580945526503/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2011/12/join-cardinality.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/3026077580945526503'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/3026077580945526503'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2011/12/join-cardinality.html' title='Join-Cardinality'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-3247692705259190586</id><published>2011-12-08T12:16:00.001-08:00</published><updated>2011-12-08T12:46:34.993-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Pipelined Functions'/><category scheme='http://www.blogger.com/atom/ns#' term='PL/SQL'/><title type='text'>Satzgenerierung mit Pipelined Function</title><content type='html'>In einem &lt;a href="http://jonathanlewis.wordpress.com/2011/12/08/test-data/#comment-42940"&gt;Kommentar im Oracle Scratchpad&lt;/a&gt; zeigt Valentin Nikotin die Verwendung einer Piplined Function als performanter Alternative zum beliebten connect-by-level-Verfahren:&lt;br /&gt;&lt;br /&gt;&lt;div class="codesnippet"&gt;&lt;pre&gt;create function generator (n pls_integer) return sys.odcinumberlist pipelined &lt;br /&gt;is&lt;br /&gt;&lt;br /&gt;begin&lt;br /&gt;&lt;br /&gt;  for i in 1 .. n loop&lt;br /&gt;    pipe row (i);&lt;br /&gt;  end loop;&lt;br /&gt;&lt;br /&gt;end;&lt;br /&gt;/&lt;br /&gt;&lt;br /&gt;select count(*) from table(generator(1e7));&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;Lesenswert ist der vorangehende Artikel des Herrn Lewis natürlich auch, aber dessen Grundgedanke war mir schon bekannt.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-3247692705259190586?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/3247692705259190586/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2011/12/satzgenerierung-mit-pipelined-function.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/3247692705259190586'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/3247692705259190586'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2011/12/satzgenerierung-mit-pipelined-function.html' title='Satzgenerierung mit Pipelined Function'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-7552650241770540453</id><published>2011-12-08T11:08:00.001-08:00</published><updated>2011-12-09T04:50:33.742-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Partitioning'/><title type='text'>ORA-08176 mit Merge und Interval Partitioning</title><content type='html'>&lt;i&gt;Interval Partitioning&lt;/i&gt; ist eine sehr praktische Vereinfachung für die Partitionierung in Version 11. Leider weist die Option aber noch einige recht unerfreuliche Bugs auf. Darüber, dass man den High_Value der initialen Partition mit Bedacht wählen sollte, habe ich &lt;a href="http://martinpreiss.blogspot.com/2011/05/highvalue-fur-interval-partitions.html"&gt;gelegentlich&lt;/a&gt; geschrieben. Heute ist mir dann&amp;nbsp;Bug 9638090 begegnet: "ORA-8176 from DML on an INTERVAL Partitioned Table OR table with deferred segment creation".&amp;nbsp;Die Grundaussage des Fehlers&amp;nbsp;&lt;i&gt;ora-08176: consistent read failure; rollback data not available&lt;/i&gt;&amp;nbsp;erläutert Mark Bobak in einem &lt;a href="http://jonathanlewis.wordpress.com/2007/09/16/index-rebuild/#comment-20994"&gt;Kommentar im Oracle Scratchpad&lt;/a&gt;: "1555 means the rollback has been overwritten, 8176 means the required rollback never existed."&amp;nbsp;In &lt;a href="https://support.oracle.com/CSP/main/article?cmd=show&amp;amp;type=NOT&amp;amp;doctype=PATCH&amp;amp;id=9638090.8"&gt;MOS&lt;/a&gt; werden die Voraussetzungen für das Auftreten des Bugs wie folgt beschrieben:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;(a) A session is performing DML on an interval partitioned table&amp;nbsp;or a table with deferred segment creation.&lt;/li&gt;&lt;li&gt;(b) The DML creates one or more interval / deferred partitions, and&lt;/li&gt;&lt;li&gt;(c) The same table is involved as the 'source' for the DML, and this&amp;nbsp;involves an index scan (hence causing a consistent read of the index).&amp;nbsp;For eg., update, merge, insert-select statements.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Ein schönes Fallbeispiel zum Thema findet man auch in einem zugehörigen&amp;nbsp;&lt;a href="https://forums.oracle.com/forums/thread.jspa?messageID=9611763"&gt;OTN-Thread&lt;/a&gt;. Als harmloser Workaround kommt eine prophylaktische Erzeugung der Partition vor dem Merge in Frage.&lt;/div&gt;&lt;br /&gt;&lt;b&gt;Nachtrag 09.12.2011&lt;/b&gt;: In der MOS-Beschreibung des Bugs wird nur ein Patch in 11.2.0.2 erwähnt; tatsächlich gibt es aber auch Patches für 11.1.0.7 und andere Versionen (wie schon Dom Brooks im OTN-Thread erwähnt; mir waren diese Patches zunächst entgangen)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-7552650241770540453?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/7552650241770540453/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2011/12/ora-08176-mit-merge-und-interval.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/7552650241770540453'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/7552650241770540453'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2011/12/ora-08176-mit-merge-und-interval.html' title='ORA-08176 mit Merge und Interval Partitioning'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-2775069361969684988</id><published>2011-12-07T01:46:00.001-08:00</published><updated>2011-12-07T06:04:03.239-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='DB-Link'/><category scheme='http://www.blogger.com/atom/ns#' term='Cost'/><category scheme='http://www.blogger.com/atom/ns#' term='CBO'/><title type='text'>Cardinality-Schätzungen für Remote-Zugriffe</title><content type='html'>Dieser Tage ist mir folgendes Phänomen begegnet, auf das ich mir noch keinen ganz klaren Reim machen kann: Ausgangspunkt war eine etwas unglücklich eingerichtete Reporting-Lösung, die grundsätzlich auf ein Star-Schema in einer Datenbank A (10.2.0.4) zugreift, aber zusätzlich auf die Daten einer Dimensionstabelle in einer Datenbank B (11.1.0.7) angewiesen ist, die über DB-Link (und Synonyme) angesprochen wird. Vor einiger Zeit ergaben sich für die Queries dieser Applikation Performance-Probleme, die zum Teil mit falschen Statistiken in Datenbank A zusammenhingen, aber z.T. auch auf fehlerhaften Einschätzungen der Cardinalities für die Dimensionstabelle in der Datenbank B beruhten. Meine erste Vermutung war, dass die falsche Cardinality durch die Korrelation von Spalteninhalten hervorgerufen wurde (in diesem Fall Produktgruppen und Lieferanten, die eben in vielen Fällen nicht unabhängig voneinander sind), weshalb ich &lt;a href="http://martinpreiss.blogspot.com/2011/03/extended-statistics.html"&gt;extended statistics&lt;/a&gt; (und Histogramme) für die fragliche Spaltenkombination anlegte. Dadurch wurden die Cardinality-Schätzungen beim Zugriff in Datenbank B besser (wenn auch nicht völlig akkurat) und auch beim Remote-Zugriff von Datenbank A aus auf die einzelne Tabelle erhielt man die gleichen Angaben:&lt;br /&gt;&lt;br /&gt;&lt;div class="codesnippet"&gt;&lt;pre&gt;select /*+ full(t) */ count(*)&lt;br /&gt;  from dim_table t&lt;br /&gt; where t.col1 = 421220&lt;br /&gt;   AND t.col2 = 20&lt;br /&gt;&lt;br /&gt;  COUNT(*)&lt;br /&gt;----------&lt;br /&gt;      2841&lt;br /&gt;&lt;br /&gt;-------------------------------------------------------------------------------&lt;br /&gt;| Id  | Operation              | Name            | Rows  | Bytes | Cost (%CPU)|&lt;br /&gt;-------------------------------------------------------------------------------&lt;br /&gt;|   0 | SELECT STATEMENT REMOTE|                 |     1 |     9 | 60397   (1)|&lt;br /&gt;|   1 |  SORT AGGREGATE        |                 |     1 |     9 |            |&lt;br /&gt;|*  2 |   TABLE ACCESS FULL    | DIM_TABLE       |   147 |  1323 | 60397   (1)|&lt;br /&gt;-------------------------------------------------------------------------------&lt;br /&gt;&lt;br /&gt;Predicate Information (identified by operation id):&lt;br /&gt;---------------------------------------------------&lt;br /&gt;&lt;br /&gt;   2 - filter("A1"."COL1"=421220 AND "A1"."COL2"=20)&lt;br /&gt;&lt;br /&gt;Note&lt;br /&gt;-----&lt;br /&gt;   - fully remote statement&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;Für das "fully remote statement" erwartet der CBO demnach 147 Sätze, was zwar von den tatsächlichen 2841 rows recht weit entfernt ist, aber immerhin mehr als die 1 (oder 2), die hier ohne die extended statistics erschien.&lt;br /&gt;&lt;br /&gt;Für die komplexeren Queries der Applikation blieb es aber trotzdem bei einer deutlichen Unterschätzung der Cardinality für den Zugriff auf DIM_TABLE. Dazu hier ein minimales Beispiel:&lt;br /&gt;&lt;br /&gt;&lt;div class="codesnippet"&gt;&lt;pre&gt;select count(*)&lt;br /&gt;  from fact_table f&lt;br /&gt;     , dim_table d&lt;br /&gt; where f.col0 = d.col0&lt;br /&gt;   and d.col1 = 421220&lt;br /&gt;   AND d.col2 = 20&lt;br /&gt;   and f.col3 = '01.12.2011'&lt;br /&gt;&lt;br /&gt;  COUNT(*)&lt;br /&gt;----------&lt;br /&gt;     13562&lt;br /&gt;&lt;br /&gt;----------------------------------------------------------------------------------------&lt;br /&gt;| Id  | Operation                | Name                   | Rows  | Bytes | Cost (%CPU)|&lt;br /&gt;----------------------------------------------------------------------------------------&lt;br /&gt;|   0 | SELECT STATEMENT         |                        |     1 |    54 |     8   (0)|&lt;br /&gt;|   1 |  SORT AGGREGATE          |                        |     1 |    54 |            |&lt;br /&gt;|   2 |   NESTED LOOPS           |                        |    24 |  1296 |     8   (0)|&lt;br /&gt;|   3 |    REMOTE                | DIM_TABLE              |     2 |    78 |     4   (0)|&lt;br /&gt;|   4 |    PARTITION RANGE SINGLE|                        |    12 |   180 |     2   (0)|&lt;br /&gt;|*  5 |     INDEX RANGE SCAN     | IDX_FACT_TABLE         |    12 |   180 |     2   (0)|&lt;br /&gt;----------------------------------------------------------------------------------------&lt;br /&gt;&lt;br /&gt;Predicate Information (identified by operation id):&lt;br /&gt;---------------------------------------------------&lt;br /&gt;&lt;br /&gt;   5 - access("F"."COL0"="A"."COL0" AND "F"."COL3"=TO_DATE(' 2011-12-01 00:00:00', 'syyyy-mm-dd hh24:mi:ss'))&lt;br /&gt;&lt;br /&gt;Remote SQL Information (identified by operation id):&lt;br /&gt;----------------------------------------------------&lt;br /&gt;&lt;br /&gt;   3 - SELECT "COL0","COL1","COL2" FROM "DIM_TABLE" "A" WHERE "COL1"=421220 AND "COL2"=20&lt;br /&gt;       (accessing 'DBL_XXX' )&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;Statt der Cardinality-Schätzung 147, die sich bei der einzelnen Ausführung des Remote SQL ergibt, erscheint hier eine 2, was im gegebenen Fall wahrscheinlich kein Problem ist, da der NL hier angemessen erscheint - aber manchmal einen geeigneteren HASH JOIN verhindern könnte. Meine Vermutung ist, dass die Extended Statistics nur beim "fully remote statement" herangezogen werden können, während das Join-Statement auf die Statistiken der Einzelspalten zurückgreift - möglicherweise, weil es in Datenbank A ausgeführt wird, also in 10.2.0.4, wo extended statistics noch gar nicht bekannt sind. Zur Prüfung dieser Annahme ein Versuch mit Ausführung in Datenbank B - erzwungen durch den DRIVING_SITE-Hint, zu dem &lt;a href="http://jonathanlewis.wordpress.com/2010/05/19/ignoring-hints-3/"&gt;Jonathan Lewis&lt;/a&gt; gelegentlich ein paar Hinweise gegeben hat.&lt;br /&gt;&lt;br /&gt;&lt;div class="codesnippet"&gt;&lt;pre&gt;select /*+ DRIVING_SITE(a) */ count(*)&lt;br /&gt;  from fact_table f&lt;br /&gt;     , dim_table d&lt;br /&gt; where f.col0 = d.col0&lt;br /&gt;   and d.col1 = 421220&lt;br /&gt;   AND d.col2 = 20&lt;br /&gt;   and f.col3 = '01.12.2011'&lt;br /&gt;&lt;br /&gt;---------------------------------------------------------------------------------------------------&lt;br /&gt;| Id  | Operation                     | Name                         | Rows  | Bytes | Cost (%CPU)|&lt;br /&gt;---------------------------------------------------------------------------------------------------&lt;br /&gt;|   0 | SELECT STATEMENT REMOTE       |                              |     1 |    38 |   395   (1)|&lt;br /&gt;|   1 |  SORT AGGREGATE               |                              |     1 |    38 |            |&lt;br /&gt;|   2 |   NESTED LOOPS                |                              |  1703 | 64714 |   395   (1)|&lt;br /&gt;|   3 |    TABLE ACCESS BY INDEX ROWID| DIM_TABLE                    |   147 |  2352 |   100   (0)|&lt;br /&gt;|*  4 |     INDEX RANGE SCAN          | IDX_DIM_TABLE                |   147 |       |     3   (0)|&lt;br /&gt;|   5 |    REMOTE                     | FACT_TABLE                   |    12 |   264 |     2   (0)|&lt;br /&gt;---------------------------------------------------------------------------------------------------&lt;br /&gt;&lt;br /&gt;Predicate Information (identified by operation id):&lt;br /&gt;---------------------------------------------------&lt;br /&gt;&lt;br /&gt;   4 - access("A1"."COL2"=20 AND "A1"."COL1"=421220)&lt;br /&gt;&lt;br /&gt;Remote SQL Information (identified by operation id):&lt;br /&gt;----------------------------------------------------&lt;br /&gt;&lt;br /&gt;   5 - SELECT "COL0","COL3" FROM "XXX"."FACT_TABLE" "A2" WHERE "COL3"=TO_DATE(' 2011-12-01&lt;br /&gt;       00:00:00', 'syyyy-mm-dd hh24:mi:ss') AND "COL0"=:1 (accessing '!' )&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;Damit ist man dann wieder bei der 147, was meine Vermutung zu bestätigen scheint. Und damit ist das Problem in diesem Fall vermutlich nicht einmal durch einen Umzug der DIM_TABLE in Datenbank A lösbar, sondern erfordert eine grundsätzlichere Behandlung (oder einen kompletten Umzug der Applikation nach B).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-2775069361969684988?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/2775069361969684988/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2011/12/cardinality-schatzungen-fur-remote.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/2775069361969684988'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/2775069361969684988'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2011/12/cardinality-schatzungen-fur-remote.html' title='Cardinality-Schätzungen für Remote-Zugriffe'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-1060800703594684367</id><published>2011-12-04T23:34:00.001-08:00</published><updated>2011-12-04T23:43:40.179-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Trace'/><title type='text'>Optimizer Trace für Queries im Cache</title><content type='html'>Obwohl ich nur recht selten das Event 10053 (aka Optimzer Trace) verwende, um die Entscheidungen des CBO genauer nachvollziehen zu können, finde ich &lt;a href="http://blogs.oracle.com/optimizer/entry/capturing_10053_trace_files_continued"&gt;Maria Colgans Hinweis&lt;/a&gt; darauf, dass man ein solches Tracing für ein im Cache vorliegendes Statement in 11.2 einfach mit Hilfe von DBMS_SQLDIAG.DUMP_TRACE erzeugen kann, sehr interessant. Vor einigen Monaten hatte Greg Rahn dazu schon mal etwas geschrieben, aber ich hatte die Möglichkeit schon wieder völlig vergessen, obwohl ich sie &lt;a href="http://martinpreiss.blogspot.com/2011/08/optimizer-trace.html"&gt;hier&lt;/a&gt; verlinkt hatte ...&lt;br /&gt;&lt;br /&gt;Die einzige ausführlichere Erläuterung zu Event 10053, die mir bekannt ist, findet sich (natürlich) in Jonathan Lewis' CBO-Buch.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-1060800703594684367?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/1060800703594684367/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2011/12/optimizer-trace-fur-queries-im-cache.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/1060800703594684367'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/1060800703594684367'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2011/12/optimizer-trace-fur-queries-im-cache.html' title='Optimizer Trace für Queries im Cache'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-4921626070870585744</id><published>2011-12-03T05:04:00.001-08:00</published><updated>2011-12-08T12:52:21.385-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='CBO'/><category scheme='http://www.blogger.com/atom/ns#' term='DML'/><title type='text'>MERGE und Transitive Closure</title><content type='html'>Eigentlich hatte ich im folgenden Zusammenhang vermutet, einem Problem des CBO auf der Spur zu sein; es ist aber wohl doch eher ein Problem des vorliegenden ETL-Prozesses...&lt;br /&gt;&lt;br /&gt;Dass der Optimizer dazu in der Lage ist, über &lt;i&gt;transitive closure&lt;/i&gt; (also die &lt;a href="http://de.wikipedia.org/wiki/Transitive_H%C3%BClle"&gt;Transitive Hülle&lt;/a&gt;) zusätzliche Prädikate zu ergänzen, kann man unter anderem in Jonathan Lewis' CBO-Buch nachlesen. Kurz zusammengefasst geht es darum, dass der CBO indirekte Abhängigkeiten erkennen kann:&lt;br /&gt;&lt;br /&gt;&lt;div class="codesnippet"&gt;&lt;pre&gt;select ...&lt;br /&gt;  from a&lt;br /&gt;     , b&lt;br /&gt; where a.id = b.id&lt;br /&gt;   and a.id = 10&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;In einem solchen Fall erkennt der CBO, dass indirekt gilt:&lt;br /&gt;&lt;br /&gt;&lt;div class="codesnippet"&gt;&lt;pre&gt;and b.id = 10&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;Bei Jonathan Lewis erfährt man auch, dass die &lt;i&gt;transitive closure&lt;/i&gt; in manchen Fällen unerwünschte Effekte hervorruft, da sie die Arithmetik des CBO durcheinander bringen kann, aber in den meisten Fällen ist sie recht nützlich. Man kann zu diesem Thema noch sehr viel mehr sagen, aber ich verweise in diesem Fall auf die üblichen Verdächtigen (neben dem Herrn Lewis wäre da noch an Randolf Geist zu denken), in deren Blogs, Büchern und Präsentationen man dazu allerlei Material finden kann.&lt;br /&gt;&lt;br /&gt;Mein eigentliches Thema ist ein anderes: ich habe dieser Tage zum wiederholten Mal gesehen, dass die Prädikat-Weitergabe über &lt;i&gt;transitive closure&lt;/i&gt; im Fall von MERGE-Statements nicht immer zu greifen scheint. Im fraglichen Fall (unter 10.2.0.4) wurde in der USING-clause des MERGEs auf einen Datums-Range eingeschränkt und diese Einschränkung wäre nützlich gewesen, um in der Zieltabelle eine Partition Elimination durchzuführen. Die zugehörige Query sah ungefähr folgendermaßen aus (hier anonymisiert und vereinfacht):&lt;br /&gt;&lt;br /&gt;&lt;div class="codesnippet"&gt;&lt;pre&gt;MERGE /*+ APPEND */ INTO FACT &lt;br /&gt;USING (SELECT A_DATE&lt;br /&gt;            , ...&lt;br /&gt;         FROM (SELECT DISTINCT &lt;br /&gt;                      A_DATE&lt;br /&gt;                    , ...&lt;br /&gt;                 FROM BASE&lt;br /&gt;                WHERE A_DATE BETWEEN :B2 AND :B1 ) &lt;br /&gt;       ) SOURCE&lt;br /&gt;    ON (     some_conditions&lt;br /&gt;         AND FACT.A_DATE = SOURCE.A_DATE ) &lt;br /&gt;  WHEN MATCHED THEN UPDATE SET ...&lt;br /&gt;  WHEN NOT MATCHED THEN INSERT ...&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;Die Query rief eine extreme Laufzeit hervor und der zugehörige Plan war:&lt;br /&gt;&lt;br /&gt;&lt;div class="codesnippet"&gt;&lt;pre&gt;------------------------------------------------------------------------------------------------------------------------------------------------&lt;br /&gt;| Id  | Operation                      | Name     | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     | Pstart| Pstop |    TQ  |IN-OUT| PQ Distrib |&lt;br /&gt;------------------------------------------------------------------------------------------------------------------------------------------------&lt;br /&gt;|   0 | MERGE STATEMENT                |          |       |       |       | 57703 (100)|          |       |       |        |      |            |&lt;br /&gt;|   1 |  MERGE                         | FACT     |       |       |       |            |          |       |       |        |      |            |&lt;br /&gt;|   2 |   PX COORDINATOR               |          |       |       |       |            |          |       |       |        |      |            |&lt;br /&gt;|   3 |    PX SEND QC (RANDOM)         | :TQ10001 | 41430 |  8981K|       | 57703   (7)| 00:13:04 |       |       |  Q1,01 | P-&amp;gt;S | QC (RAND)  |&lt;br /&gt;|   4 |     VIEW                       |          |       |       |       |            |          |       |       |  Q1,01 | PCWP |            |&lt;br /&gt;|   5 |      HASH JOIN OUTER           |          | 41430 |  8981K|       | 57703   (7)| 00:13:04 |       |       |  Q1,01 | PCWP |            |&lt;br /&gt;|   6 |       BUFFER SORT              |          |       |       |       |            |          |       |       |  Q1,01 | PCWC |            |&lt;br /&gt;|   7 |        PX RECEIVE              |          | 41430 |  5502K|       | 17408   (6)| 00:03:57 |       |       |  Q1,01 | PCWP |            |&lt;br /&gt;|   8 |         PX SEND PARTITION (KEY)| :TQ10000 | 41430 |  5502K|       | 17408   (6)| 00:03:57 |       |       |        | S-&amp;gt;P | PART (KEY) |&lt;br /&gt;|   9 |          VIEW                  |          | 41430 |  5502K|       | 17408   (6)| 00:03:57 |       |       |        |      |            |&lt;br /&gt;|  10 |           SORT UNIQUE          |          | 41430 |  2022K|  6520K| 17408   (6)| 00:03:57 |       |       |        |      |            |&lt;br /&gt;|  11 |            FILTER              |          |       |       |       |            |          |       |       |        |      |            |&lt;br /&gt;|  12 |             TABLE ACCESS FULL  | BASE     | 41430 |  2022K|       | 16966   (6)| 00:03:51 |       |       |        |      |            |&lt;br /&gt;|  13 |       PX PARTITION RANGE ALL   |          |   895M|    71G|       | 39789   (7)| 00:09:01 |     1 |   362 |  Q1,01 | PCWC |            |&lt;br /&gt;|  14 |        TABLE ACCESS FULL       | FACT     |   895M|    71G|       | 39789   (7)| 00:09:01 |     1 |   362 |  Q1,01 | PCWP |            |&lt;br /&gt;------------------------------------------------------------------------------------------------------------------------------------------------&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;Demnach wurden also alle FACT-Partitionen von 1 bis 362 gelesen, obwohl der Partition-Key A_DATE als Join-Bedingung verwendet wurde und im USING auf einen Range eingeschränkt wurde. Die Einschränkung betraf übrigens genau einen Monat, was der Partitionierungs-Strategie der FACT-Tabelle entspricht. Eine Ersetzung der Bindewerte durch Literale änderte das Verhalten nicht.&lt;br /&gt;&lt;br /&gt;An einem der folgenden Tage habe ich dann die semantisch redundante Sub-Query im Using herausgenommen und erhielt einen Plan, bei dem die &lt;i&gt;transitive closure&lt;/i&gt; wieder zu funktionieren schien - und damit dann auch die Partition Elimination; so jedenfalls deutete ich die KEY-KEY-Einschränkungen (der zeitliche Abstand erklärt dann auch die veränderten Cardinalities):&lt;br /&gt;&lt;br /&gt;&lt;div class="codesnippet"&gt;&lt;pre&gt;MERGE /*+ APPEND */ INTO FACT &lt;br /&gt;USING (SELECT DISTINCT &lt;br /&gt;              A_DATE&lt;br /&gt;            , ...&lt;br /&gt;         FROM BASE&lt;br /&gt;        WHERE A_DATE BETWEEN :B2 AND :B1 ) &lt;br /&gt;       ) SOURCE&lt;br /&gt;    ON (     some_conditions&lt;br /&gt;         AND FACT.A_DATE = SOURCE.A_DATE ) &lt;br /&gt;  WHEN MATCHED THEN UPDATE SET ...&lt;br /&gt;  WHEN NOT MATCHED THEN INSERT ...&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;Liefert folgenden Plan:&lt;br /&gt;&lt;br /&gt;&lt;div class="codesnippet"&gt;&lt;pre&gt;-----------------------------------------------------------------------------------------------------------------------------------------------&lt;br /&gt;| Id  | Operation                               | Name      | Rows  | Bytes |TempSpc| Cost (%CPU)| Pstart| Pstop |    TQ  |IN-OUT| PQ Distrib |&lt;br /&gt;-----------------------------------------------------------------------------------------------------------------------------------------------&lt;br /&gt;|   0 | MERGE STATEMENT                         |           | 19294 |  5916K|       | 43473   (1)|       |       |        |      |            |&lt;br /&gt;|   1 |  MERGE                                  | FACT      |       |       |       |            |       |       |        |      |            |&lt;br /&gt;|   2 |   PX COORDINATOR                        |           |       |       |       |            |       |       |        |      |            |&lt;br /&gt;|   3 |    PX SEND QC (RANDOM)                  | :TQ10001  | 19294 |  4182K|       | 43473   (1)|       |       |  Q1,01 | P-&amp;gt;S | QC (RAND)  |&lt;br /&gt;|   4 |     VIEW                                |           |       |       |       |            |       |       |  Q1,01 | PCWP |            |&lt;br /&gt;|   5 |      NESTED LOOPS OUTER                 |           | 19294 |  4182K|       | 43473   (1)|       |       |  Q1,01 | PCWP |            |&lt;br /&gt;|   6 |       BUFFER SORT                       |           |       |       |       |            |       |       |  Q1,01 | PCWC |            |&lt;br /&gt;|   7 |        PX RECEIVE                       |           |       |       |       |            |       |       |  Q1,01 | PCWP |            |&lt;br /&gt;|   8 |         PX SEND ROUND-ROBIN             | :TQ10000  |       |       |       |            |       |       |        | S-&amp;gt;P | RND-ROBIN  |&lt;br /&gt;|   9 |          VIEW                           |           | 19294 |  2562K|       |  4881   (9)|       |       |        |      |            |&lt;br /&gt;|  10 |           SORT UNIQUE                   |           | 19294 |   942K|  3048K|  4881   (9)|       |       |        |      |            |&lt;br /&gt;|  11 |            FILTER                       |           |       |       |       |            |       |       |        |      |            |&lt;br /&gt;|  12 |             TABLE ACCESS FULL           | BASE      | 19294 |   942K|       |  4674   (9)|       |       |        |      |            |&lt;br /&gt;|  13 |       PARTITION RANGE ITERATOR          |           |     1 |    86 |       |     0   (0)|   KEY |   KEY |  Q1,01 | PCWP |            |&lt;br /&gt;|  14 |        TABLE ACCESS BY LOCAL INDEX ROWID| FACT      |     1 |    86 |       |     0   (0)|   KEY |   KEY |  Q1,01 | PCWP |            |&lt;br /&gt;|  15 |         INDEX RANGE SCAN                | PK_FACT   |     1 |       |       |     0   (0)|   KEY |   KEY |  Q1,01 | PCWP |            |&lt;br /&gt;-----------------------------------------------------------------------------------------------------------------------------------------------&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;Allerdings hätte ich einen FTS-Zugriff auf FACT vorgezogen. Mit einem FULL-Hint für FACT bekam ich dann aber wieder den ursprünglichen Plan mit dem Zugriff auf alle Partitionen. Die Planänderung hatte also nichts mit meiner Umformulierung zu tun, sondern ergab sich aus den veränderten Statistiken. Die Elimination funktionierte im FTS-Fall erst wieder, als ich das DISTINCT entfernte, das vermutlich eingebaut werden musste, um "ORA-01427: single-row subquery returns more than one row" zu vermeiden (da die BASE-Tabelle offenbar tatsächlich Duplikate enthalten kann). Ohne DISTINCT und mit FULL-Hint ergibt sich:&lt;br /&gt;&lt;br /&gt;&lt;div class="codesnippet"&gt;&lt;pre&gt;----------------------------------------------------------------------------------------------------------------------------&lt;br /&gt;| Id  | Operation                     | Name     | Rows  | Bytes | Cost (%CPU)| Pstart| Pstop |    TQ  |IN-OUT| PQ Distrib |&lt;br /&gt;----------------------------------------------------------------------------------------------------------------------------&lt;br /&gt;|   0 | MERGE STATEMENT               |          | 19294 |  5916K| 33548   (9)|       |       |        |      |            |&lt;br /&gt;|   1 |  MERGE                        | FACT     |       |       |            |       |       |        |      |            |&lt;br /&gt;|   2 |   PX COORDINATOR              |          |       |       |            |       |       |        |      |            |&lt;br /&gt;|   3 |    PX SEND QC (RANDOM)        | :TQ10002 | 19294 |  2562K| 33548   (9)|       |       |  Q1,02 | P-&amp;gt;S | QC (RAND)  |&lt;br /&gt;|   4 |     VIEW                      |          |       |       |            |       |       |  Q1,02 | PCWP |            |&lt;br /&gt;|   5 |      FILTER                   |          |       |       |            |       |       |  Q1,02 | PCWC |            |&lt;br /&gt;|   6 |       HASH JOIN OUTER BUFFERED|          | 19294 |  2562K| 33548   (9)|       |       |  Q1,02 | PCWP |            |&lt;br /&gt;|   7 |        BUFFER SORT            |          |       |       |            |       |       |  Q1,02 | PCWC |            |&lt;br /&gt;|   8 |         PX RECEIVE            |          | 19294 |   942K|  4674   (9)|       |       |  Q1,02 | PCWP |            |&lt;br /&gt;|   9 |          PX SEND HASH         | :TQ10000 | 19294 |   942K|  4674   (9)|       |       |        | S-&amp;gt;P | HASH       |&lt;br /&gt;|  10 |           TABLE ACCESS FULL   | BASE     | 19294 |   942K|  4674   (9)|       |       |        |      |            |&lt;br /&gt;|  11 |        PX RECEIVE             |          |  2237K|   183M| 28872   (9)|       |       |  Q1,02 | PCWP |            |&lt;br /&gt;|  12 |         PX SEND HASH          | :TQ10001 |  2237K|   183M| 28872   (9)|       |       |  Q1,01 | P-&amp;gt;P | HASH       |&lt;br /&gt;|  13 |          PX BLOCK ITERATOR    |          |  2237K|   183M| 28872   (9)|   KEY |   KEY |  Q1,01 | PCWC |            |&lt;br /&gt;|  14 |           TABLE ACCESS FULL   | FACT     |  2237K|   183M| 28872   (9)|   KEY |   KEY |  Q1,01 | PCWP |            |&lt;br /&gt;----------------------------------------------------------------------------------------------------------------------------&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;Demnach verhindert das DISTINCT die Weitergabe der Datumseinschränkung über &lt;i&gt;transitive closure&lt;/i&gt; und das Partition Pruning (jedenfalls im FTS-Fall). Offenbar kann der CBO nicht erkennen, dass das DISTINCT keinen Einfluß auf die angegebenen Datums-Ranges haben kann. Die KEY-KEY-Einschränkungen im Fall des Index-Zugriffs sind übrigens das Ergebnis des NL-Joins, der ein dynamisches Pruning ermöglicht, wie Randolf Geist in seinem Kommentar erklärt. Um das Lesen der überflüssigen SOURCE-Partitionen zu vermeiden, hätte man demnach folgende Möglichkeiten:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Umbau der ETL-Logik zur Vermeidung von Duplikaten in der Tabelle BASE - dann wäre das DISTINCT verzichtbar.&lt;/li&gt;&lt;li&gt;Ergänzung einer zusätzlichen Zeiteinschränkung in der ON-clause (WHERE FACT.A_DATE BETWEEN :B2 AND :B1), so dass man sich nicht mehr auf die &lt;i&gt;transitive closure&lt;/i&gt; verlassen muss.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;b&gt;Nachtrag 05.12.2011&lt;/b&gt;: ich habe den Eintrag heute Morgen noch mal überarbeitet, nachdem mir klar wurde, dass meine Schlußfolgerungen nicht wirklich schlüssig waren - erst im Anschluß daran habe ich gesehen, dass Randolf Geist bereits einen Kommentar zum Thema abgegeben hatte, der ebenfalls auf diese Fehleinschätzungen hinwies (und der dadurch vielleicht nicht mehr ganz zum Eintrag zu passen scheint).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-4921626070870585744?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/4921626070870585744/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2011/12/merge-und-transitive-closure.html#comment-form' title='3 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/4921626070870585744'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/4921626070870585744'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2011/12/merge-und-transitive-closure.html' title='MERGE und Transitive Closure'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-5262567477047523795</id><published>2011-11-30T07:26:00.001-08:00</published><updated>2011-11-30T11:11:19.305-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SQL Server'/><title type='text'>Locks und Latches im SQL Server</title><content type='html'>Bei &lt;a href="http://blog.kejser.org/2011/11/09/thread-synchronization-in-sql-server/"&gt;Thomas Kejser&lt;/a&gt; gibt's eine sehr schöne Erläuterung zum Verhalten von Locks und Latches im SQL Server und zu den zugehörigen Analysemöglichkeiten, die die DMVs liefern.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-5262567477047523795?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/5262567477047523795/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2011/11/locks-und-latches-im-sql-server.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/5262567477047523795'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/5262567477047523795'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2011/11/locks-und-latches-im-sql-server.html' title='Locks und Latches im SQL Server'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-2047995577862912758</id><published>2011-11-29T01:23:00.001-08:00</published><updated>2011-11-29T04:56:28.732-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Administration'/><title type='text'>Recyclebin</title><content type='html'>Über den Recyclebin haben zuletzt &lt;a href="http://hoopercharles.wordpress.com/2011/11/28/bin-index-found-in-the-execution-plan-digging-through-the-recycle-bin/"&gt;Charles Hooper&lt;/a&gt; und &lt;a href="http://timurakhmadeev.wordpress.com/2011/11/28/recycle-bin/"&gt;Timur Akhmadeev&lt;/a&gt; geschrieben:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Hooper zeigt, wie es dazu kommen kann, dass in Zugriffsplänen Indizes mit BIN%-Namen erscheinen: diese Namen ergeben sich, wenn eine Tabelle über flashback wiederhergestellt wird - die Tabelle erhält dann wieder ihren urspünglichen Namen, aber die zugehörigen Indizes behalten ihren Recyclebin-Namen (den man natürlich auch wieder ändern kann). Wie üblich liefert der Autor alle erdenklichen Beispiele und Links zum Thema.&lt;/li&gt;&lt;li&gt;Ahkmadeev erwähnt einen Fall, in dem ein INSERT INTO ... VALUES-Statement für einen einzelnen Satz über eine Stunde lang hing und CPU verbrannte, weil es mit einem rekursiven DELETE FROM RECYCLEBIN$ kollidierte, das (vermutlich in einem Loop) mehr als eine Million mal ausgeführt wurde.&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-2047995577862912758?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/2047995577862912758/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2011/11/recyclebin.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/2047995577862912758'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/2047995577862912758'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2011/11/recyclebin.html' title='Recyclebin'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-4849503933395712216</id><published>2011-11-27T01:31:00.001-08:00</published><updated>2011-11-27T02:02:30.669-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Hints'/><title type='text'>Beschreibende Index-Hints</title><content type='html'>Jonathan Lewis erläutert in seinem &lt;a href="http://jonathanlewis.wordpress.com/2011/11/24/index-hints/"&gt;Blog&lt;/a&gt; beschreibende Index-Hints, die seit Version 10 verfügbar sind. Dabei wird nicht der Name eines Index angegeben, sondern die Tabelle, der zugehörige Query-Block und die Reihenfolge der relevanten Spalten.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-4849503933395712216?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/4849503933395712216/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2011/11/beschreibende-index-hints.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/4849503933395712216'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/4849503933395712216'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2011/11/beschreibende-index-hints.html' title='Beschreibende Index-Hints'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-7446999828574112812</id><published>2011-11-26T11:47:00.001-08:00</published><updated>2011-11-26T11:52:24.664-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PL/SQL'/><title type='text'>Details zu DBMS_METADATA</title><content type='html'>Zwei interessante Notizen zu DBMS_METADATA:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://oraganism.wordpress.com/2011/11/23/dbms_metadata-get_ddl-and-select_catalog_role/"&gt;Neil Johnson&lt;/a&gt; zeigt, dass für die Verwendung von DBMS_METADATA die SELECT_CATALOG_ROLE benötigt wird.&lt;/li&gt;&lt;li&gt;&lt;a href="http://blog.sydoracle.com/2011/11/dbmsmetadata-and-hashed-passwords.html"&gt;Gary Myers&lt;/a&gt; führt vor, wie man mit Hilfe von DBMS_METADATA auf die Hash-Version von Benutzer-Paßwörtern zugreifen kann (was in 11g über DBA_USERS nicht mehr möglich ist)&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-7446999828574112812?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/7446999828574112812/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2011/11/details-zu-dbmsmetadata.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/7446999828574112812'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/7446999828574112812'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2011/11/details-zu-dbmsmetadata.html' title='Details zu DBMS_METADATA'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-407725518327254873</id><published>2011-11-25T12:38:00.001-08:00</published><updated>2011-11-25T12:39:54.591-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Trigger'/><title type='text'>DROP-Operationen verhindern</title><content type='html'>Carsten Czarski zeigt in seinem &lt;a href="http://sql-plsql-de.blogspot.com/2011/11/drop-table-sind-sie-sicher.html"&gt;Blog&lt;/a&gt;, wie man das versehentliche Löschen von Datenbankobjekten mit Hilfe von Triggern erschweren kann.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-407725518327254873?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/407725518327254873/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2011/11/drop-operationen-verhindern.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/407725518327254873'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/407725518327254873'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2011/11/drop-operationen-verhindern.html' title='DROP-Operationen verhindern'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-7607124461727754574</id><published>2011-11-24T12:19:00.001-08:00</published><updated>2011-11-24T12:26:57.435-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Analytics'/><title type='text'>LISTAGG</title><content type='html'>Da ich heute - wahrscheinlich zum wiederholten Mal - die LISTAGG-Funktion in Releases unterhalb von 11.2 verwenden wollte, ehe mir einfiel, dass sie dort noch nicht existiert, hier ein Hinweis auf &lt;a href="http://www.oracle-base.com/articles/misc/StringAggregationTechniques.php"&gt;Tim Halls Erläuterung&lt;/a&gt; diverser Methoden zur Aggregation von Strings, die unter anderem auch die handliche WM_CONCAT-Funktion enthält. Weitere Hinweise auch zur Performance verschiedener Verfahren findet man bei &lt;a href="http://www.oracle-developer.net/display.php?id=306"&gt;Adrian Billington&lt;/a&gt; (bei dem ich dieser Tage andauernd lande), der auch einen Link auf &lt;a href="http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:2196162600402"&gt;Tom Kytes klassische STRAGG-Funktion&lt;/a&gt; liefert.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-7607124461727754574?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/7607124461727754574/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2011/11/listagg.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/7607124461727754574'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/7607124461727754574'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2011/11/listagg.html' title='LISTAGG'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-5337260226425211068</id><published>2011-11-22T11:44:00.001-08:00</published><updated>2011-11-22T11:51:04.526-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PL/SQL'/><category scheme='http://www.blogger.com/atom/ns#' term='Cost'/><title type='text'>CBO-Schätzungen für PL/SQL</title><content type='html'>Randolf Geist stellt in seinem &lt;a href="http://oracle-randolf.blogspot.com/2011/11/doag-2011-unconference-wrap-up.html"&gt;Blog&lt;/a&gt; eine Liste von Artikeln zusammen, auf die er in seinen DOAG-Unconference-Sessions (die ich gerne gesehen hätte) Bezug genommen hat - vor allem auf Adrian Billingtons Beiträge zum Thema und auf Joze Senegacniks grundlegendes Kapitel im Band &lt;i&gt;Expert Oracle Practices&lt;/i&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-5337260226425211068?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/5337260226425211068/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2011/11/cbo-schatzungen-fur-plsql.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/5337260226425211068'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/5337260226425211068'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2011/11/cbo-schatzungen-fur-plsql.html' title='CBO-Schätzungen für PL/SQL'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-3940148915446428822</id><published>2011-11-22T06:02:00.001-08:00</published><updated>2011-12-13T11:32:55.299-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Index'/><title type='text'>Index Organized Tables</title><content type='html'>Jonathan Lewis hat ein paar &lt;a href="http://jonathanlewis.wordpress.com/2011/11/22/iots/"&gt;Links&lt;/a&gt; zu &lt;i&gt;Index Organized Tables&lt;/i&gt; (IOT) aufgelistet: vor allem führt er Martin Widlakes Artikelserie zum Thema auf.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Nachtrag 13.12.2011&lt;/b&gt;: Noch ein &lt;a href="http://jonathanlewis.wordpress.com/2011/12/11/iot-trap/"&gt;Hinweis&lt;/a&gt; vom Herrn Lewis: die including clause stellt nicht notwendig sicher, dass eine Spalte im Index-Segment landet (und nicht im Overflow-Segment), da Oracle die Spalten unter Umständen intern umstellt.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-3940148915446428822?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/3940148915446428822/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2011/11/index-organized-tables.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/3940148915446428822'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/3940148915446428822'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2011/11/index-organized-tables.html' title='Index Organized Tables'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-1275038105197017664</id><published>2011-11-19T12:38:00.001-08:00</published><updated>2011-11-19T12:41:13.765-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Star Transformation'/><title type='text'>Cardinality Probleme bei Star Transformation</title><content type='html'>Randolf Geist erläutert in seinem &lt;a href="http://oracle-randolf.blogspot.com/2011/11/star-transformation-and-cardinality.html"&gt;Blog&lt;/a&gt;, dass der CBO bei der &lt;i&gt;Star Transformation&lt;/i&gt; zu falschen Cardinality-Schätzungen kommt, wenn mehrere Dimensionen in einer einzigen Tabelle zusammengefasst sind.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-1275038105197017664?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/1275038105197017664/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2011/11/cardinality-probleme-bei-star.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/1275038105197017664'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/1275038105197017664'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2011/11/cardinality-probleme-bei-star.html' title='Cardinality Probleme bei Star Transformation'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-6950185306543825363</id><published>2011-11-18T07:54:00.001-08:00</published><updated>2011-11-21T12:46:46.583-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Trace'/><category scheme='http://www.blogger.com/atom/ns#' term='Scripts'/><title type='text'>Instabile Pläne</title><content type='html'>Kerry Osborne hat vor einiger Zeit ein extrem nützliches Script zur Bestimmung von Queries veröffentlicht, deren Ressourcen-Nutzung nach einer Planänderung dramatisch verändert ist. Hintergrundinformationen zum Thema (und weitere Analysescripte) findet man in seinem &lt;a href="http://kerryosborne.oracle-guy.com/2008/10/unstable-plans/"&gt;Blog&lt;/a&gt;. Ich habe das Script behutsam erweitert (und weniger behutsam formatiert) und meiner eigenen Sammlung hinzugefügt:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://kerryosborne.oracle-guy.com/scripts/unstable_plans.sql"&gt;Kerry Osbornes Script&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="https://sites.google.com/site/mporaclewiki/home/oracle/scripts/unstable_plans-sql"&gt;Meine Version&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;Basierend auf dem Ergebnis kann man dann in DBA_HIST_SQLSTAT prüfen, ob die Änderung eine Verbesserung oder eine Verschlechterung darstellte. Und anschließend kann mann dann mit Hilfe von DBMS_XPLAN.DISPLAY_AWR die im &lt;i&gt;Automatic Workload Repository&lt;/i&gt; vorliegenden Pläne ermitteln.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-6950185306543825363?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/6950185306543825363/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2011/11/instabile-plane.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/6950185306543825363'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/6950185306543825363'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2011/11/instabile-plane.html' title='Instabile Pläne'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-7558550122550378724</id><published>2011-11-16T02:26:00.001-08:00</published><updated>2012-01-18T07:44:59.710-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Statistiken'/><title type='text'>Statistik-Erfassung für große partitionierte Tabellen</title><content type='html'>Eine kurze Notiz zur Frage: wie sollten Statistiken für große partitionierte Tabellen aktualisiert werden? Darauf gibt es viele Anworten, zwei davon findet man im &lt;a href="http://optimizermagic.blogspot.com/2009/02/maintaining-statistics-on-large.html"&gt;Blog der cbo-Entwickler&lt;/a&gt;. Darin erläutert Maria Colgan die Optionen für 10.2.0.4 und 11:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;In Version 10.2.0.4 kann man mit Hilfe von DBMS_STATS.COPY_TABLE_STATS die Statistiken einer Partition in eine andere Partition kopieren, wobei die Statistiken der &lt;i&gt;partition key &lt;/i&gt;Spalte sinnvoll angepasst werden; so wie ich's verstehe, bleiben die übrigen Spalten-Statistiken identisch, was aber in der Regel kein Problem sein sollte, da die meisten Spalten der für das Feature in Frage kommenden großen historisch partitionierten Faktentabellen pro Partition ähnliche Eigenschaften haben sollten&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;In Version 11 kann man die globale Statistik-Erhebung für große partitionierte Objekte auf INCREMENTAL umstellen, was bedeutet, dass nur noch die Deltas analysiert werden müssen und distinkte Anzahlen über eine Synopsis bestimmt werden. Damit sollte das Thema in Version 11 deutlich unproblematischer sein. Weitere Details zum Thema findet man bei &lt;a href="http://structureddata.org/2008/07/16/oracle-11g-incremental-global-statistics-on-partitioned-tables/"&gt;Greg Rahn&lt;/a&gt;, der auch noch mal auf ein &lt;a href="http://dl.acm.org/citation.cfm?id=1376616.1376721&amp;amp;coll=ACM&amp;amp;dl=ACM&amp;amp;type=series&amp;amp;idx=SERIES473&amp;amp;part=series&amp;amp;WantType=Proceedings&amp;amp;title=SIGMOD"&gt;weiterführendes White-Paper&lt;/a&gt; verweist (das auch bei Frau Colgan erwähnt wird).&lt;/li&gt;&lt;/ul&gt;Doug Burns hat zum Thema der Statistiken für partitionierte Tabellen eine ganze Serie von Blog-Artikeln geschrieben, die neben weiteren relevanten Artikeln von Randolf Geist und Kerry Osborne im &lt;a href="http://jonathanlewis.wordpress.com/2010/03/17/partition-stats/"&gt;Oracle Sratchpad&lt;/a&gt; verlinkt sind. Dort stellt Jonathan Lewis fest: "It’s possible to spend ages talking about the best ways of collecting, or creating, statistics on partitioned tables." Und da hat er offenbar mal wieder Recht.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Nachtrag 18.01.2012&lt;/b&gt;: inzwischen hat &lt;a href="http://oracle-randolf.blogspot.com/2012/01/incremental-partition-statistics-review.html"&gt;Randolf Geist&lt;/a&gt; ein paar wichtige Hinweise zur inkrementellen Erhebung von Partitionsstatistiken veröffentlicht - und vor allem auch ein paar potentielle Probleme des Features aufgeführt.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-7558550122550378724?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/7558550122550378724/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2011/11/statistik-erfassung-fur-groe.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/7558550122550378724'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/7558550122550378724'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2011/11/statistik-erfassung-fur-groe.html' title='Statistik-Erfassung für große partitionierte Tabellen'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-9175174551902334466</id><published>2011-11-13T10:58:00.001-08:00</published><updated>2011-11-16T02:43:54.505-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Trace'/><title type='text'>Evil Events</title><content type='html'>Tanel Poder erwähnt in seinem &lt;a href="http://blog.tanelpoder.com/2011/11/13/evil-things-are-happening-in-oracle/"&gt;Blog&lt;/a&gt; ein paar Events, die Oracle offenbar moralisch bewertet, nämlich&amp;nbsp;&lt;i&gt;Inject Evil Literals&lt;/i&gt; und&amp;nbsp;&lt;i&gt;Inject Evil Identifiers&lt;/i&gt;. Nahe liegend ist dann die von Oracle vorgeschlagene &lt;i&gt;Action&lt;/i&gt; zu den Fehlermeldungen: "never set this event".&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-9175174551902334466?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/9175174551902334466/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2011/11/evil-events.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/9175174551902334466'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/9175174551902334466'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2011/11/evil-events.html' title='Evil Events'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-6981180763004501884</id><published>2011-11-12T13:34:00.001-08:00</published><updated>2011-11-12T13:40:21.593-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Trace'/><category scheme='http://www.blogger.com/atom/ns#' term='External Tables'/><title type='text'>TKPROF mit External Table anzeigen</title><content type='html'>&lt;a href="http://www.oracle-developer.net/display.php?id=516"&gt;Adrian Billington&lt;/a&gt; erläutert, wie man TKPROF-Ausgabe-Dateien mit Hilfe des External Table Preprocessors in sqlplus verfügbar machen kann:&lt;br /&gt;&lt;blockquote class="tr_bq"&gt;Using the simple techniques described in this article, we are now able to find a trace file, read it using the TRACEFILE_XT read-only external table, profile it with preprocessor external tables over TKProf or OraSRP and read the reports without leaving our IDE once. We can even read HTML reports in a browser window generated from within SQL*Plus without any additional keystrokes. For readers who work regularly with trace files, these are good productivity improvements!&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-6981180763004501884?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/6981180763004501884/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2011/11/tkprof-mit-external-table-anzeigen.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/6981180763004501884'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/6981180763004501884'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2011/11/tkprof-mit-external-table-anzeigen.html' title='TKPROF mit External Table anzeigen'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-7642645423238667206</id><published>2011-11-11T02:47:00.001-08:00</published><updated>2011-11-11T05:55:32.820-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='DML'/><title type='text'>Logging in Error-Tabelle</title><content type='html'>Dieser Tage wurde ich an die Möglichkeit erinnert, Fehler bei DML-Operationen in einer DML-Error-Logging-Tabelle zu protokollieren, was ich mal wieder als Option betrachte, an PL/SQL vorbei zu kommen...&lt;br /&gt;&lt;br /&gt;Der &lt;a href="http://download.oracle.com/docs/cd/E11882_01/server.112/e25554/transform.htm#DWHSG8337"&gt;Database Data Warehousing Guide&lt;/a&gt; erläutert diese Option grundsätzlich folgendermaßen:&lt;br /&gt;&lt;blockquote class="tr_bq"&gt;DML error logging extends existing DML functionality by enabling you to specify the name of an error logging table into which Oracle Database should record errors encountered during DML operations. This enables you to complete the DML operation in spite of any errors, and to take corrective action on the erroneous rows at a later time.&lt;br /&gt;&lt;br /&gt;This DML error logging table consists of several mandatory control columns and a set of user-defined columns that represent either all or a subset of the columns of the target table of the DML operation using a data type that is capable of storing potential errors for the target column.&lt;/blockquote&gt;Ein detailliertes Beispiel für das Vorgehen gibt's bei &lt;a href="http://www.oracle-base.com/articles/10g/DmlErrorLogging_10gR2.php"&gt;Tim Hall&lt;/a&gt;; für den eiligen Nutzer hier eine kleinere Demonstration:&lt;br /&gt;&lt;br /&gt;&lt;div class="codesnippet"&gt;&lt;pre&gt;-- Anlage einer Tabelle TEST&lt;br /&gt;create table test&lt;br /&gt;( id number&lt;br /&gt;, name varchar2(10)&lt;br /&gt;, description varchar2(32)&lt;br /&gt;, some_data number(8));&lt;br /&gt;&lt;br /&gt;-- Anlage einer passenden ERROR-Table zur Tabelle TEST&lt;br /&gt;-- mit Hilfe des dbms_errorlog-Packages&lt;br /&gt;exec dbms_errlog.create_error_log (dml_table_name =&amp;gt; 'test');&lt;br /&gt;&lt;br /&gt;-- Die erzeugte ERROR-Tabelle besitzt das Präfix ERR$_&lt;br /&gt;-- und enthält alle Spalten der Zieltabelle als VARCHAR2(4000)&lt;br /&gt;-- und zusätzlich diverse Spalten zur Speicherung von Fehler-&lt;br /&gt;-- Informationen&lt;br /&gt;desc ERR$_TEST&lt;br /&gt;&lt;br /&gt;Name                                      Null?    Typ&lt;br /&gt;----------------------------------------- -------- -------------------&lt;br /&gt;ORA_ERR_NUMBER$                                    NUMBER&lt;br /&gt;ORA_ERR_MESG$                                      VARCHAR2(2000)&lt;br /&gt;ORA_ERR_ROWID$                                     ROWID&lt;br /&gt;ORA_ERR_OPTYP$                                     VARCHAR2(2)&lt;br /&gt;ORA_ERR_TAG$                                       VARCHAR2(2000)&lt;br /&gt;ID                                                 VARCHAR2(4000)&lt;br /&gt;NAME                                               VARCHAR2(4000)&lt;br /&gt;DESCRIPTION                                        VARCHAR2(4000)&lt;br /&gt;SOME_DATA                                          VARCHAR2(4000)&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;Details zum Format der ERROR-Tabelle liefert der &lt;a href="http://download.oracle.com/docs/cd/E11882_01/server.112/e25494/tables004.htm#ADMIN11636"&gt;Administrator's Guide&lt;/a&gt;:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;ORA_ERR_NUMBER$: Oracle error number&lt;/li&gt;&lt;li&gt;ORA_ERR_MESG$: Oracle error message text&lt;/li&gt;&lt;li&gt;ORA_ERR_ROWID$: Rowid of the row in error (for update and delete)&lt;/li&gt;&lt;li&gt;ORA_ERR_OPTYP$: Type of operation: insert (I), update (U), delete (D) Note: Errors from the update clause and insert clause of a MERGE operation are distinguished by the U and I values.&lt;/li&gt;&lt;li&gt;ORA_ERR_TAG$: Value of the tag supplied by the user in the error logging clause&lt;/li&gt;&lt;/ul&gt;Mit Hilfe der Klausel LOG ERRORS INTO ... kann man nun eine DML-Operation zum erfolgreichen Abschluss bringen, die sonst auf Fehler gelaufen wäre:&lt;br /&gt;&lt;br /&gt;&lt;div class="codesnippet"&gt;&lt;pre&gt;-- mein Insert klappt erst mal nicht&lt;br /&gt;insert into test&lt;br /&gt;select rownum&lt;br /&gt;     , 'bla'&lt;br /&gt;     , 'irgendwas'&lt;br /&gt;     , rownum * 1000000&lt;br /&gt;  from dual&lt;br /&gt;connect by level &amp;lt; 10000;&lt;br /&gt;&lt;br /&gt;     , rownum * 1000000&lt;br /&gt;              *&lt;br /&gt;FEHLER in Zeile 5:&lt;br /&gt;ORA-01438: Wert größer als die angegebene Gesamststellenzahl, die für diese Spalte zulässig ist&lt;br /&gt;&lt;br /&gt;-- aber mit der LOG ERRORS INTO Klausel geht's durch&lt;br /&gt;insert into test&lt;br /&gt;select rownum&lt;br /&gt;     , 'bla'&lt;br /&gt;     , 'irgendwas'&lt;br /&gt;     , rownum * 1000000&lt;br /&gt;  from dual&lt;br /&gt;connect by level &amp;lt; 10000&lt;br /&gt;log errors into err$_test ('insert') reject limit unlimited;&lt;br /&gt;&lt;br /&gt;99 Zeilen wurden erstellt.&lt;br /&gt;--&amp;gt; die übrigen 9900 Sätze landen dabei in ERR$_TEST&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;Offenbar wird dabei nur der erste auftretende Fehler protokolliert:&lt;br /&gt;&lt;div class="codesnippet"&gt;&lt;pre&gt;-- Löschung der Daten der ERROR-Tabelle:&lt;br /&gt;truncate table err$_test;&lt;br /&gt;&lt;br /&gt;-- dazu ein INSERT, das für mehrere Spalten unverdauliche Daten enthält:&lt;br /&gt;insert into test &lt;br /&gt;values ( 1&lt;br /&gt;       , 'blaaaaaaaaaaaaaaaaaaaaaa'&lt;br /&gt;       , 'ssssssssssssssssssssssssssspppppppppppppppppppaaaaaaaaaaaaaaaaaaaaaaaaammmmmmmmmmmmmmmmm'&lt;br /&gt;       , 123456789000000000000)&lt;br /&gt;log errors into err$_test ('insert') reject limit unlimited;&lt;br /&gt;&lt;br /&gt;0 Zeilen wurden erstellt.&lt;br /&gt;&lt;br /&gt;--&amp;gt; was für die Spalten 2 - 4 nicht klappen kann&lt;br /&gt;&lt;br /&gt;-- Die Metadaten zum Fehler sind dann:&lt;br /&gt;&lt;br /&gt;select ora_err_number$&lt;br /&gt;     , ora_err_mesg$&lt;br /&gt;     , ora_err_rowid$&lt;br /&gt;     , ora_err_optyp$&lt;br /&gt;     , ora_err_tag$&lt;br /&gt;  from err$_test;&lt;br /&gt;&lt;br /&gt;ORA_ERR_NUMBER$ ORA_ERR_MESG$                  ORA_ERR_ROWID$  ORA_ERR_OPTYP$  ORA_ERR_TAG$&lt;br /&gt;--------------- ------------------------------ --------------- --------------- ---------------&lt;br /&gt;          12899 ORA-12899: Wert zu groß für Sp                 I               insert&lt;br /&gt;                alte "DBADMIN"."TEST"."NAME" (&lt;br /&gt;                aktuell: 24, maximal: 10)&lt;br /&gt;&lt;br /&gt;-- dann folgen in err$_test die Werte des gescheiterten INSERTs.&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;Die Dokumentation (in diesem Fall die &lt;a href="http://download.oracle.com/docs/cd/E11882_01/server.112/e26088/statements_9014.htm#SQLRF55101"&gt;SQL Language Reference&lt;/a&gt;) nennt noch folgende Fälle, in denen der Mechanismus nicht verwendbar ist - also ein Fehler auftritt und ein Rollback durchgeführt wird:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Verletzung von &lt;i&gt;deferred constraints&lt;/i&gt;.&lt;/li&gt;&lt;li&gt;Direct-Path-Operationen, die eine unique constraint oder index violation hervorrufen.&lt;/li&gt;&lt;li&gt;Update oder Merge Operationen, die eine unique constraint oder index violation hervorrufen.&lt;/li&gt;&lt;/ul&gt;Für LONG, LOB und Objekt-Typen gelten spezielle Bedingungen, deren Aufzählung ich mir hier aber mit Verweis auf die Doku spare.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-7642645423238667206?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/7642645423238667206/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2011/11/logging-in-error-tabelle.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/7642645423238667206'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/7642645423238667206'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2011/11/logging-in-error-tabelle.html' title='Logging in Error-Tabelle'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-8965347966320459044</id><published>2011-11-09T03:04:00.000-08:00</published><updated>2011-11-12T12:19:01.907-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Parallel'/><title type='text'>Auto DOP in 11.2</title><content type='html'>Dieser Tage haben sich &lt;a href="http://uhesse.wordpress.com/2011/10/12/auto-dop-differences-of-parallel_degree_policyautolimited/"&gt;Uwe Hesse&lt;/a&gt;, &lt;a href="http://oracle-randolf.blogspot.com/2011/10/auto-dop-and-direct-path-inserts.html"&gt;Randolf Geist&lt;/a&gt; und &lt;a href="http://www.pythian.com/news/27867/secrets-of-oracles-automatic-degree-of-parallelism/"&gt;Gwen Shapira&lt;/a&gt; mit dem neuen &lt;i&gt;Auto Degree Of Parallelism&lt;/i&gt; (DOP) Feature in 11.2 beschäftigt.&lt;br /&gt;&lt;br /&gt;Eine grundlegende Diskussion des Features liefert Frau Shapira in ihrem Blog:&lt;br /&gt;&lt;blockquote class="tr_bq"&gt;at least in the white papers and presentations it sounds like a very attractive solution. There are two levels to Auto DOP:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Limited – when accessing tables and indexes that have been declared with parallel clause, Oracle will decide on the degree of parallelism based on the query and system resources.&lt;/li&gt;&lt;li&gt;Auto – Oracle will decide on degree of parallelism for every query. In addition two exciting new features are enabled: parallel statement queuing and in-memory parallel execution.&lt;/li&gt;&lt;/ul&gt;&lt;/blockquote&gt;Der Herr Hesse erläutert die Wirkung des Parameters&amp;nbsp;parallel_degree_policy und die daraus resultierende Wirksamkeit von Hints:&lt;br /&gt;&lt;blockquote class="tr_bq"&gt;parallel_degree_policy=LIMITED will give you the DOP you request and compute an appropriate DOP only with a parallel degree of DEFAULT as an attribute of the table. Use this parameter if you trust that your applications/designers know why they use a certain DOP. parallel_degree_policy=AUTO will overrule any specific DOP you gave – except the new 11g parallel (n) Hint – and consider to do things in parallel for all tables even without a Hint or Degree.&lt;/blockquote&gt;Beim Herrn Geist geht's um die Beobachtung, dass ein&amp;nbsp;parallel_degree_policy=auto die Verwendung von &lt;i&gt;direct path inserts&lt;/i&gt; hervorrufen kann, was zwar in gewisser Weise folgerichtig ist, aber die üblichen Nebeneffekte des direct path hervorruft (INSERT oberhalb der HWM und "ORA-12838: cannot read/modify an object after modifying it in parallel"), wobei besonders&amp;nbsp;ORA-12838 ungünstige Wirkungen haben kann:&lt;br /&gt;&lt;blockquote class="tr_bq"&gt;An existing application logic might break because it attempts to re-access the object after the now direct-path insert within the the same transaction which will end up with an "ORA-12838: cannot read/modify an object after modifying it in parallel".&lt;/blockquote&gt;Bei den Herren Hesse und Geist gibt's die dort üblichen Testfällen, mit deren Hilfe die Effekte nachvollzogen und überprüft werden können.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Nachtrag 12.11.2011&lt;/b&gt;: In seinem Kommentar weist Randolf Geist darauf hin, dass Uwe Hesses Beobachtung der Ausschaltung von Parallel-Hints durch parallel_degree_policy=AUTO wahrscheinlich auf Bug 10628995 beruht. In seinem Kommentar zu Uwe Hesses Blog kommt Greg Rahn zur gleichen Einschätzung.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-8965347966320459044?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/8965347966320459044/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2011/11/auto-dop-in-112.html#comment-form' title='2 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/8965347966320459044'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/8965347966320459044'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2011/11/auto-dop-in-112.html' title='Auto DOP in 11.2'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-7320197537428500089</id><published>2011-11-07T11:06:00.000-08:00</published><updated>2011-11-07T11:06:10.286-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tools'/><category scheme='http://www.blogger.com/atom/ns#' term='SQL Server'/><title type='text'>SQL Sentry Plan Explorer</title><content type='html'>Dieser Tage bin ich auf den kostenlosen &lt;a href="http://www.sqlsentry.net/plan-explorer/sql-server-query-view.asp"&gt;SQL Sentry Plan Explorer&lt;/a&gt; gestossen, ein Tool, mit dessen Hilfe sich &lt;i&gt;Execution Plans&lt;/i&gt; im SQL Server deutlich klarer visualisieren lassen als mit den Bordmitteln im SSMS (die selbst aber schon ganz brauchbar sind). Das Tool lässt sich als Add-In zum SSMS einrichten und erfordert eine Installation von .Net 4.0. Zu den Features des Tools gehören das &lt;i&gt;Plan Diagram&lt;/i&gt; mit einer klaren Hervorhebung der kostspieligsten Abschnitte eines Plans, der &lt;i&gt;Join Tree&lt;/i&gt; mit einer Visualisierung der Tabellenverknüpfungen und nicht zuletzt der &lt;i&gt;Plan Tree&lt;/i&gt;, der den Zugriffsplan so darstellt, wie man es aus Oracle z.B. vom dbms_display-Package kennt. Nett und - wie gesagt - kostenlos.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-7320197537428500089?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/7320197537428500089/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2011/11/sql-sentry-plan-explorer.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/7320197537428500089'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/7320197537428500089'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2011/11/sql-sentry-plan-explorer.html' title='SQL Sentry Plan Explorer'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-6785723113413101721</id><published>2011-11-04T03:29:00.000-07:00</published><updated>2011-11-04T03:29:53.362-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Latches'/><title type='text'>Mutex Waits</title><content type='html'>&lt;a href="http://andreynikolaev.wordpress.com/2011/10/25/mutex-waits-part-ii-cursor-pin-s-in-oracle-11-2-_mutex_wait_scheme0-steps-out-of-shadow/"&gt;Andrey Nikolaev&lt;/a&gt; hat mal wieder einen interessanten Artikel über das Verhalten von Mutexes veröffentlicht. Dieses Verhalten hat sich offenbar in 11.2 deutlich verändert, so dass Mutex Waits nun ziemlich gut analysierbar und damit auch optimierbar sind. Für das Verhalten vor 11.2 galt dabei Folgendes (die Aufzählungen sind dabei jeweils Zitate aus der Quelle):&lt;br /&gt;&lt;ul&gt;&lt;li&gt;“Cursor: pin S” was pure wait for CPU. Long “cursor: pin S” waits indicated CPU starvation.&lt;/li&gt;&lt;li&gt;&amp;nbsp;Mutex contention was almost invisible to Oracle Wait Interface.&lt;/li&gt;&lt;li&gt;&amp;nbsp;Spin time to acquire mutex was accounted as CPU time. It was service time, not waiting time.&lt;/li&gt;&lt;/ul&gt;In 11.2 gilt:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Oracle 11.2 Wait Interface computes &lt;strong&gt;“wait time”&lt;/strong&gt; as a duration between the first spin and successful mutex acquisition. As a result we observe only one wait in &lt;strong&gt;v$system_event&lt;/strong&gt;.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Oracle 11.2 mutex wait includes both spinning and waiting.&lt;/strong&gt;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;the 11.2.0.2 the “cursor: pin S” wait event no more starve CPU&lt;/strong&gt;. This reduces probability of CPU thrashing due to mutex waits.&lt;/li&gt;&lt;/ul&gt;Es folgen noch allerlei Informationen zu den (underscore) Parametern, die das Verhalten der Mutexe steuern, aber die Details will ich hier nicht wiederholen&amp;nbsp;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-6785723113413101721?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/6785723113413101721/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2011/11/mutex-waits.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/6785723113413101721'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/6785723113413101721'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2011/11/mutex-waits.html' title='Mutex Waits'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-1833950062050841351</id><published>2011-11-02T09:18:00.000-07:00</published><updated>2011-11-02T09:18:59.304-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ETL'/><title type='text'>OWB und ODI</title><content type='html'>&lt;a href="http://www.rittmanmead.com/2011/10/oracle-warehouse-builder-and-data-integrator/"&gt;Peter Scott&lt;/a&gt; von &lt;i&gt;Rittman Mead Consulting&lt;/i&gt; verspricht eine Artikelserie, in der er die Unterschiede zwischen &lt;i&gt;Oracle Warehouse Builder&lt;/i&gt; (OWB) und &lt;i&gt;Oracle Data Integrator&lt;/i&gt; (ODI) erläutern will und liefert zunächst eine Zusammenfassung der konzeptionellen Gemeinsamkeiten und Unterschiede:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;"Both ODI and OWB have a similar (I am being very simplistic here)  three-component design of: a metadata repository, a development  environment where the developer defines the processes and data flows and  a runtime component that executes the code and flows."&lt;/li&gt;&lt;li&gt;Speicherung des Repositories:&lt;/li&gt;&lt;ul&gt;&lt;li&gt;OWB: Repository ist vorinstalliert in einer Oracle-DB&lt;/li&gt;&lt;li&gt;das ODI Repository wird mit Hilfe des Oracle Fusion Middleware’s Repository Creation Utility in einer unterstützten DB angelegt (nicht notwendig Oracle)&amp;nbsp;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Standard-Operationen:&lt;/li&gt;&lt;ul&gt;&lt;li&gt;"with OWB the key parts of the IDE are those for the development of  MAPPINGS and (optionally) the design of process flows to orchestrate  mappings." &lt;/li&gt;&lt;li&gt; "In the ODI world think INTERFACES for mappings and PACKAGES for process flows. This is simplistic though as ODI also has PROCEDURES (code developed in  one of the ODI supported languages) and LOAD PLANS (multiple packages  orchestrated to execute in serial or parallel)"&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Umsetzung der Operationen:&lt;/li&gt;&lt;ul&gt;&lt;li&gt;OWB mappings require the developer to include all of the components  needed to facilitate the mapping – we connect source columns to target  columns through a logic flow of joiners, filters, expressions,  aggregates and a whole palette of other activities. Typically, this  would generate &lt;b&gt;a single, but large, SQL statement with much use of  in-line views&lt;/b&gt;." (immer PL/SQL) &lt;/li&gt;&lt;li&gt;"ODI interfaces are simply about connecting source columns  to target columns in a logical relationship (we also create  expressions, joins and filters here) and&lt;b&gt; allowing the physical  implementation to be supplied by a knowledge module&lt;/b&gt;." (kann auch einfach SQL sein) &lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;Meine Erfahrungen mit dem OWB sind sehr beschränkt und mit dem ODI habe ich noch nie ernsthaft gearbeitet, aber aus meiner Sicht sind die gravierendsten Einschränkungen des OWB (abgesehen von seiner fehlenden Zukunft), dass er oft recht suboptimales SQL (in PL/SQL-Verpackung) erzeugt und viele neuere Datenbankfeatures kalt lächeln ignoriert - und das scheint im Fall des ODI dann mit Hilfe des &lt;i&gt;knowledge modules&lt;/i&gt; stärker beeinflußbar zu sein. Dass grafische ETL-Tools bei der Definition relativ einfacher Transformationen oft sehr umständliche GUI-Darstellungen erzeugen, ist vermutlich eher ein allgemeines Problem solcher Werkzeuge. Und dass der PL/SQL-Code des OWB in nahezu jedem Fall ausufernd groß wird, ist vermutlich nur für Kommandozeilen-Fetischisten wie mich ein Problem.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-1833950062050841351?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/1833950062050841351/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2011/11/owb-und-odi.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/1833950062050841351'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/1833950062050841351'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2011/11/owb-und-odi.html' title='OWB und ODI'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-6871308899180724809</id><published>2011-10-28T00:25:00.000-07:00</published><updated>2011-10-28T00:26:41.787-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PL/SQL'/><title type='text'>DBMS_SCHEDULER Grundlagen</title><content type='html'>Dieser Tage habe ich mich zum ersten Mal ein wenig mit dem DBMS_SCHEDULER beschäftigt und nehme das zum Anlass, ein paar grundlegende Dinge aufzuschreiben und einige Links zu notieren. Grundsätzlich dient der Scheduler zur Definition Zeit- oder Event-gesteuerter Aktionen und bietet dabei deutlich umfangreichere Funktionen als DBMS_JOB - z.B. ist es möglich komplexe Zeitpläne und Ausführungs-Windows zu definieren, Abhängigkeiten anzugeben und ein detailliertes Monitoring der Ausführungen zu erzeugen. Hier nur ein ganz einfaches Beispiel:&lt;br /&gt;&lt;br /&gt;&lt;div class="codesnippet"&gt;&lt;pre&gt;-- Loeschung des Jobs (wenn vorhanden)&lt;br /&gt;exec dbms_scheduler.drop_job (job_name =&amp;gt; 'my_scheduler_test_job');&lt;br /&gt;&lt;br /&gt;-- Job-Definition&lt;br /&gt;begin&lt;br /&gt;  dbms_scheduler.create_job (&lt;br /&gt;    job_name        =&amp;gt; 'my_scheduler_test_job',&lt;br /&gt;    job_type        =&amp;gt; 'PLSQL_BLOCK',&lt;br /&gt;    job_action      =&amp;gt; 'BEGIN TEST_PROC; END;',&lt;br /&gt;    start_date      =&amp;gt; systimestamp,&lt;br /&gt;    repeat_interval =&amp;gt; 'FREQ=DAILY;BYHOUR=09;BYMINUTE=15',&lt;br /&gt;    end_date        =&amp;gt; null,&lt;br /&gt;    enabled         =&amp;gt; true,&lt;br /&gt;    comments        =&amp;gt; 'belangloser Test-Job zur Ausfuehrung einer belanglosen Test-Prozedur.');&lt;br /&gt;&lt;br /&gt;end;&lt;br /&gt;/&lt;br /&gt;&lt;br /&gt;-- sofortiger Start des Jobs unabhaengig vom Zeitplan&lt;br /&gt;exec dbms_scheduler.run_job('my_scheduler_test_job')&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;In der Job-Definition kann man die Aktion und den Zeitplan direkt angeben (wie im Beispiel), man kann aber auch zuvor definierte Schedules und Programme verwenden. Eine umfangreiche Darstellung der Möglichkeiten bietet Tim Halls unten verlinkte Artikelserie, während die beiden einführenden Artikel eher die Grundlagen der Verwendung des Schedulers beleuchten (allerdings deutlich heller, als ich das hier gemacht habe).&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.trivadis.com/uploads/tx_cabagdownloadarea/Oracle_Scheduler.pdf"&gt;Oracle-Scheduler, Eine Alternative zu "professionellen" Schedulern?&lt;/a&gt; Sven Vetter erläutert in diesem Trivadis-Dokument die Verbesserungen des Schedulers in 10.2 und führt aus, was ihm noch fehlt&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.ordix.de/ORDIXNews/1_2005/oracle_10g_jobsteuerung.html"&gt;Jobsteuerung mit dbms_scheduler&lt;/a&gt;: einführender Artikel von Kathrin Hammerschmidt bei Ordix&lt;/li&gt;&lt;li&gt; &lt;a href="http://www.held-informatik.de/tipps-tricks/plsql-packages/steuerung-von-datenbank-jobs.html"&gt;Job-Steuerung in Oracle Datenbanken&lt;/a&gt;: einführender Artikel auf der Website von Held Informatik&lt;/li&gt;&lt;li&gt;Tim Halls Serie zu den Features des Schedulers in aktuellen Oracle-Versionen&lt;/li&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.oracle-base.com/articles/10g/Scheduler10g.php"&gt;10.1&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.oracle-base.com/articles/10g/SchedulerEnhancements_10gR2.php"&gt;10.2&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.oracle-base.com/articles/11g/SchedulerEnhancements_11gR1.php"&gt;11.1&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-6871308899180724809?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/6871308899180724809/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2011/10/dbmsscheduler-grundlagen.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/6871308899180724809'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/6871308899180724809'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2011/10/dbmsscheduler-grundlagen.html' title='DBMS_SCHEDULER Grundlagen'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-6705651783178845152</id><published>2011-10-27T05:31:00.000-07:00</published><updated>2011-10-27T05:31:36.297-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PL/SQL'/><title type='text'>Abhängigkeitsanalysen mit UTL_XML.PARSEQUERY</title><content type='html'>Philipp Salvisberg erläutert in seinem &lt;a href="http://www.salvis.com/blog/?p=117"&gt;Blog&lt;/a&gt;, wie man&amp;nbsp;UTL_XML.PARSEQUERY als Hilfsmittel zum Parsen verwenden kann, um damit alle View-Spalten zu finden, denen eine bestimmte Spalte einer Basistabelle zugrunde liegt.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-6705651783178845152?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/6705651783178845152/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2011/10/abhangigkeitsanalysen-mit.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/6705651783178845152'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/6705651783178845152'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2011/10/abhangigkeitsanalysen-mit.html' title='Abhängigkeitsanalysen mit UTL_XML.PARSEQUERY'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-9213230364098173681</id><published>2011-10-25T06:52:00.000-07:00</published><updated>2011-10-25T06:52:06.342-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Trace'/><title type='text'>SQL_EXEC_ID</title><content type='html'>&lt;a href="http://blog.tanelpoder.com/2011/10/24/what-the-heck-is-the-sql-execution-id-sql_exec_id/"&gt;Tanel Poder&lt;/a&gt; hat sich etwas intensiver mit den technischen Details der SQL_EXEC_ID beschäftigt und dabei - natürlich - ein paar recht interessante Beobachtungen gemacht; unter anderem liefert er eine Erklärung für den seltsamen Wert&amp;nbsp;16777216, über den ich mich auch gelegentlich schon gewundert hatte.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-9213230364098173681?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/9213230364098173681/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2011/10/sqlexecid.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/9213230364098173681'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/9213230364098173681'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2011/10/sqlexecid.html' title='SQL_EXEC_ID'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-4892729144293419091</id><published>2011-10-25T04:56:00.000-07:00</published><updated>2012-01-14T06:17:24.584-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Plan Management'/><title type='text'>Planüberschreibung mit DBMS_SPM</title><content type='html'>Dom Brooks zeigt in seinem &lt;a href="http://orastory.wordpress.com/2011/10/13/no-need-to-change-source-code-hint-it-using-a-baseline/"&gt;Blog&lt;/a&gt; ein sehr handliches Beispiel dafür, wie man SQL Plan Baselines einsetzen kann, um den Zugriffsplan einer Query zu ändern, ohne das Statement anpassen zu müssen. Alles was man dafür benötigt, sind der (exakte) &amp;nbsp;SQL_TEXT der ursprünglichen Query, sowie SQL_ID und PLAN_HASH_VALUE der optimierten Version. Interessant sind auch die ergänzenden Informationen des Folgeartikels&amp;nbsp;&lt;a href="http://orastory.wordpress.com/2011/10/14/quick-overview-of-loading-plans-into-a-baseline/"&gt;Quick overview of loading plans into a baseline&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;In diesem Zusammenhang interessant ist auch noch der Hinweis von &lt;a href="http://blogs.oracle.com/optimizer/entry/does_the_use_of_sql"&gt;Maria Colgan&lt;/a&gt;, dass für die Verwendung von&amp;nbsp;&lt;i&gt;SQL Plan Management&lt;/i&gt; (SPM) und den in DBMS_SPM enthaltenen Prozeduren keine zusätzliche Lizenzierung erforderlich ist. SPM ist Bestandteil der Enterprise Edition.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-4892729144293419091?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/4892729144293419091/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2011/10/planuberschreibung-mit-dbmsspm.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/4892729144293419091'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/4892729144293419091'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2011/10/planuberschreibung-mit-dbmsspm.html' title='Planüberschreibung mit DBMS_SPM'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-4945643239530986673</id><published>2011-10-24T11:49:00.000-07:00</published><updated>2011-10-24T11:52:49.621-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Privat'/><title type='text'>Florenz</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-Zp1aD05wD9g/TqWzGvzwwoI/AAAAAAAAAYU/n-dlB_c4lxg/s1600/IMG_0212.JPG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="300" src="http://1.bp.blogspot.com/-Zp1aD05wD9g/TqWzGvzwwoI/AAAAAAAAAYU/n-dlB_c4lxg/s400/IMG_0212.JPG" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Von Fiesole aus gesehen.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-4945643239530986673?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/4945643239530986673/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2011/10/florenz.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/4945643239530986673'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/4945643239530986673'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2011/10/florenz.html' title='Florenz'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-Zp1aD05wD9g/TqWzGvzwwoI/AAAAAAAAAYU/n-dlB_c4lxg/s72-c/IMG_0212.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-6566696072492953090</id><published>2011-10-21T02:33:00.000-07:00</published><updated>2011-10-21T02:33:49.780-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='CBO'/><title type='text'>Technical Papers des cbo Teams</title><content type='html'>Das Team der cbo-Entwickler hat ein paar &lt;a href="http://blogs.oracle.com/optimizer/entry/optimizer_technical_papers1"&gt;Links&lt;/a&gt; zu technischen Papers bereitgestellt, die sicher alle eine genauere Lektüre verdienen.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-6566696072492953090?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/6566696072492953090/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2011/10/technical-papers-des-cbo-teams.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/6566696072492953090'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/6566696072492953090'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2011/10/technical-papers-des-cbo-teams.html' title='Technical Papers des cbo Teams'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-8325992565639013939</id><published>2011-10-21T00:54:00.000-07:00</published><updated>2011-10-21T02:05:03.766-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Statistiken'/><title type='text'>block_sample für gather_table_stats</title><content type='html'>Dass man die Sample-Größe für die dbms_stats-Prozeduren seit Release 11 in aller Regel nicht mehr anpassen muss, da die AUTO_SAMPLE_SIZE sehr gute Resultate liefert, hat &lt;a href="http://structureddata.org/2007/09/17/oracle-11g-enhancements-to-dbms_stats/"&gt;Greg Rahn&lt;/a&gt; schon vor einigen Jahren festgestellt:&lt;br /&gt;&lt;blockquote&gt;Overall the 11g DBMS_STATS has been enhanced to gather stats in less time, but in my opinion the significant enhancement is to AUTO_SAMPLE_SIZE which yields near 100% sample accuracy in 10% sample time.&lt;/blockquote&gt;Trotzdem hatte ich mir zuletzt Gedanken darüber gemacht, ob man mit der Option &lt;i&gt;block_sample&lt;/i&gt; die Laufzeit der Statistik-Erstellung signifikant reduzieren kann. Die &lt;a href="http://download.oracle.com/docs/cd/E11882_01/appdev.112/e25788/d_stats.htm#ARPLS68582"&gt;Dokumentation&lt;/a&gt; erklärt diese Option folgendermaßen:&lt;br /&gt;&lt;blockquote&gt;Whether or not to use random block sampling instead of random row sampling. Random block sampling is more efficient, but if the data is not randomly distributed on disk, then the sample values may be somewhat correlated. Only pertinent when doing an estimate statistics.&lt;/blockquote&gt;Ein kleiner Test zeigt, dass die Option tatsächlich einen deutlichen Einfluss auf die Leseoperationen der Statistikerfassung hat:&lt;br /&gt;&lt;br /&gt;&lt;div class="codesnippet"&gt;&lt;pre&gt;-- Anlage einer relativ großen Testtabelle&lt;br /&gt;drop table big_t;&lt;br /&gt;&lt;br /&gt;create table big_t&lt;br /&gt;as&lt;br /&gt;with&lt;br /&gt;base_data&lt;br /&gt;as&lt;br /&gt;(&lt;br /&gt;select rownum id1&lt;br /&gt;  from dual&lt;br /&gt;connect by level &amp;lt;= 1000000&lt;br /&gt;)&lt;br /&gt;,&lt;br /&gt;mult&lt;br /&gt;as&lt;br /&gt;(&lt;br /&gt;select rownum id2&lt;br /&gt;  from dual&lt;br /&gt;connect by level &amp;lt;= 30&lt;br /&gt;)&lt;br /&gt;select rownum id&lt;br /&gt;     , 'aaa' col2&lt;br /&gt;  from mult&lt;br /&gt;     , base_data;&lt;br /&gt;&lt;br /&gt;-- Statistikerhebung&lt;br /&gt;exec dbms_stats.gather_table_stats(user, 'BIG_T')&lt;br /&gt; &lt;br /&gt;exec dbms_stats.gather_table_stats(user, 'BIG_T', estimate_percent=&amp;gt;1)&lt;br /&gt;&lt;br /&gt;exec dbms_stats.gather_table_stats(user, 'BIG_T', estimate_percent=&amp;gt;1, block_sample=&amp;gt;TRUE)&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;Die Ergebnisse für die angesprochenen Versionen sehen folgendermaßen aus:&lt;br /&gt;&lt;br /&gt;&lt;table border="1" bordercolor="#666666" cellpadding="0" cellspacing="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;/tr&gt;&lt;tr bgcolor="#CCCCCC" bordercolor="#333333"&gt;&lt;td nowrap=""&gt;&lt;div align="center"&gt;&lt;span style="font-family: 'Courier New', Courier, mono; font-size: x-small;"&gt;&lt;strong&gt;Version&lt;/strong&gt;&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;&lt;td&gt;&lt;div align="center"&gt;&lt;span style="font-family: 'Courier New', Courier, mono; font-size: x-small;"&gt;&lt;strong&gt;Parameter&lt;/strong&gt;&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;&lt;td&gt;&lt;div align="center"&gt;&lt;span style="font-family: 'Courier New', Courier, mono; font-size: x-small;"&gt;&lt;strong&gt;Laufzeit&lt;/strong&gt;&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr bordercolor="#CCCCCC"&gt;&lt;td&gt;&lt;div align="left"&gt;&lt;span style="font-family: 'Courier New', Courier, mono; font-size: x-small;"&gt;10.2.0.4&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;&lt;td&gt;&lt;div align="left"&gt;&lt;span style="font-family: 'Courier New', Courier, mono; font-size: x-small;"&gt;ohne&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;&lt;td&gt;&lt;div align="right"&gt;&lt;span style="font-family: 'Courier New', Courier, mono; font-size: x-small;"&gt;33.86 sec.&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr bordercolor="#CCCCCC"&gt;&lt;td&gt;&lt;div align="left"&gt;&lt;span style="font-family: 'Courier New', Courier, mono; font-size: x-small;"&gt;10.2.0.4&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;&lt;td&gt;&lt;div align="left"&gt;&lt;span style="font-family: 'Courier New', Courier, mono; font-size: x-small;"&gt;estimate_percent: 1&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;&lt;td&gt;&lt;div align="right"&gt;&lt;span style="font-family: 'Courier New', Courier, mono; font-size: x-small;"&gt;12.31 sec.&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr bordercolor="#CCCCCC"&gt;&lt;td&gt;&lt;div align="left"&gt;&lt;span style="font-family: 'Courier New', Courier, mono; font-size: x-small;"&gt;10.2.0.4&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;&lt;td&gt;&lt;div align="left"&gt;&lt;span style="font-family: 'Courier New', Courier, mono; font-size: x-small;"&gt;estimate_percent: 1; block_sampling&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;&lt;td&gt;&lt;div align="right"&gt;&lt;span style="font-family: 'Courier New', Courier, mono; font-size: x-small;"&gt;1.01 sec.&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr bordercolor="#CCCCCC"&gt;&lt;td&gt;&lt;div align="left"&gt;&lt;span style="font-family: 'Courier New', Courier, mono; font-size: x-small;"&gt;11.1.0.7&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;&lt;td&gt;&lt;div align="left"&gt;&lt;span style="font-family: 'Courier New', Courier, mono; font-size: x-small;"&gt;ohne&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;&lt;td&gt;&lt;div align="right"&gt;&lt;span style="font-family: 'Courier New', Courier, mono; font-size: x-small;"&gt;13.07 sec.&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr bordercolor="#CCCCCC"&gt;&lt;td&gt;&lt;div align="left"&gt;&lt;span style="font-family: 'Courier New', Courier, mono; font-size: x-small;"&gt;11.1.0.7&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;&lt;td&gt;&lt;div align="left"&gt;&lt;span style="font-family: 'Courier New', Courier, mono; font-size: x-small;"&gt;estimate_percent: 1&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;&lt;td&gt;&lt;div align="right"&gt;&lt;span style="font-family: 'Courier New', Courier, mono; font-size: x-small;"&gt;2.40 sec.&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr bordercolor="#CCCCCC"&gt;&lt;td&gt;&lt;div align="left"&gt;&lt;span style="font-family: 'Courier New', Courier, mono; font-size: x-small;"&gt;11.1.0.7&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;&lt;td&gt;&lt;div align="left"&gt;&lt;span style="font-family: 'Courier New', Courier, mono; font-size: x-small;"&gt;estimate_percent: 1; block_sampling&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;&lt;td&gt;&lt;div align="right"&gt;&lt;span style="font-family: 'Courier New', Courier, mono; font-size: x-small;"&gt;1.78 sec.&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;Dazu noch ein paar Kommentare:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;die deutlichen Laufzeitunterschiede ergeben sich aus der unterschiedlichen I/O-Performance der beiden Testsysteme (sehr langsame Platten für 10.2.0.4)&lt;/li&gt;&lt;li&gt;ein 10046er Trace zeigt, dass die zugehörigen Queries mit der Klausel SAMPLE bzw. SAMPLE BLOCK ausgeführt werden.&lt;/li&gt;&lt;li&gt;mit SAMPLE BLOCK sinkt die Anzahl der erforderlichen LIOs und PIOs in beiden Versionen; Für die Queries mit SAMPLE werden alle Tabellenblocks gelesen, während&amp;nbsp;SAMPLE BLOCK tatsächlich nur auf einen gewissen Prozentsatz liest, der ungefähr dem geforderten Wert entspricht (ermittelt mit AUTOTRACE in 11.1.0.7):&lt;/li&gt;&lt;ul&gt;&lt;li&gt;FTS ohne Sampling:&amp;nbsp;30812 &amp;nbsp;consistent gets&lt;/li&gt;&lt;li&gt;FTS mit sample(1):&amp;nbsp;30812 &amp;nbsp;consistent gets&lt;/li&gt;&lt;li&gt;FTS mit&amp;nbsp;sample block (1):&amp;nbsp;327 &amp;nbsp;consistent gets&lt;/li&gt;&lt;li&gt;FTS mit&amp;nbsp;sample block (10):&amp;nbsp;3399 &amp;nbsp;consistent gets&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;Für die Erstellung von Statistiken für sehr große Tabellen könnte die block_sample-Option demnach auch in Versionen &amp;gt;= 11 immer noch interessant sein, da sie die erforderlichen Leseoperationen dramatisch reduzieren kann. Das gilt aber natürlich nur dann, wenn sichergestellt ist, dass die Blocks ähnliche Verteilungsmuster besitzen wie die gesamte Tabelle. Die Qualität der mit Hilfe von Sampling erzeugten Statistiken wäre aber ohnehin noch mal ein anderes Thema.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-8325992565639013939?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/8325992565639013939/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2011/10/blocksample-fur-gathertablestats.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/8325992565639013939'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/8325992565639013939'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2011/10/blocksample-fur-gathertablestats.html' title='block_sample für gather_table_stats'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-960500007776136929</id><published>2011-10-20T06:57:00.000-07:00</published><updated>2011-10-20T06:57:24.639-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Statistiken'/><title type='text'>Dynamic Sampling</title><content type='html'>Heute wollte ich einer Query einen &lt;i&gt;dynamic_sampling&lt;/i&gt; Hint mitgeben und fand bei &lt;a href="http://jonathanlewis.wordpress.com/2010/02/23/dynamic-sampling/"&gt;Jonathan Lewis&lt;/a&gt; günstigerweise den Hinweis, dass man diesen Hint nicht pro Tabelle setzen muss, sondern auf Query-Ebene definieren kann.&lt;br /&gt;&lt;br /&gt;Eine Liste mit einer Beschreibung der Sampling-Levels (und weitere Informationen zum Thema) findet man bei &lt;a href="http://blogs.oracle.com/optimizer/entry/dynamic_sampling_and_its_impact_on_the_optimizer"&gt;Maria Colgan&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-960500007776136929?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/960500007776136929/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2011/10/dynamic-sampling.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/960500007776136929'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/960500007776136929'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2011/10/dynamic-sampling.html' title='Dynamic Sampling'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-6266390676812991674</id><published>2011-10-19T09:37:00.000-07:00</published><updated>2011-10-19T09:38:19.142-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Statistiken'/><title type='text'>Optimizer Statistics Präsentation bei Open World 2011</title><content type='html'>Das Team der cbo Entwickler (bzw. Maria Colgan) hat bei der Oracle Open World 2011 offenbar eine sehr schöne Präsentation zur Erstellung und Rolle der Statistiken gehalten, und die zugehörigen &lt;a href="https://oracleus.wingateweb.com/published/oracleus2011/sessions/13961/13961_Cho134332.pdf"&gt;Folien&lt;/a&gt; ins Netz gestellt. Hier eine kurze Liste mit Punkten, die mir erinnerungswürdig erscheinen:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;dbms_stats &lt;/li&gt;&lt;ul&gt;&lt;li&gt;üblicherweise sollte man nur die ersten Parameter der GATHER_%_STATS-Prozeduren benötigen (Schema Name, Table Name, Partition Name)&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;Weitere Parameter: &lt;/li&gt;&lt;ul&gt;&lt;li&gt;Inkrementelle Statistiken: "Ability to accurate generate global statistics from partition level statistics"&lt;/li&gt;&lt;li&gt;Concurrent Statistics Gathering: "Ability to gather statistics on multiple objects concurrently under a GATHER_SCHEMA_STATS command"&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Default-Werte der Prozeduren können auf verschiedenen Ebenen gesetzt werden&lt;/li&gt;&lt;li&gt;Sample Size: in 11g sollte man immer die default AUTO_SAMPLE_SIZE verwenden, da sie die Performance eines 10% Samples mit der Genauigkeit eines 100% Samples verbindet (dazu hatte Greg Rahn vor längerer Zeit gebloggt)&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;&amp;nbsp;Index-Statistiken&lt;/li&gt;&lt;ul&gt;&lt;li&gt;"Index statistics are automatically gathered during creation and maintained by GATHER_TABLE_STATS"&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Histogramme&lt;/li&gt;&lt;ul&gt;&lt;li&gt;"Default create histogram on any column that has been used in the WHERE clause or GROUP BY of a statement AND has a data skew" ("Relies on column usage information gathered at compilation time and stored in SYS.COL_USAGE$")&lt;/li&gt;&lt;li&gt;Cardinality-Berechnung:&lt;/li&gt;&lt;ul&gt;&lt;li&gt;für popular values ("Popular value means values that are the endpoint for two or more buckets") -&amp;gt; (Anzahl Endpoint Buckets/Gesamtanzahl Buckets)/Anzahl rows in der Tabelle&lt;/li&gt;&lt;li&gt;für non popular values ("Non-popular value means values that are the endpoint for only one bucket or are not an endpoint at all") -&amp;gt; DENSITY X * Anzahl rows in der Tabelle ("Density from 10.2.0.4 is calculated on the fly based on histogram information and is not the value show in USER_HISTOGRAMS")&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Probleme:&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Bind Peeking (in 11.2 durch Adaptive Cursor Sharing kein Problem mehr)&lt;/li&gt;&lt;li&gt;Nearly popular values ("Nearly popular value means the value is classified as&lt;br /&gt;non-popular but the density calculation is not accurate for them"): werden unterschätzt; behebbar durch dynamic sampling hint im Statement)&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;li&gt;Extended Statistics&lt;/li&gt;&lt;ul&gt;&lt;li&gt;für column groups: zur Darstellung von Korrelationen&lt;/li&gt;&lt;li&gt;für expressions (virtual columns)&lt;/li&gt;&lt;li&gt;automatische Erzeugung mit Hilfe von dbms_stats.seed_col_usage + Monitoring von Workload + dbms_stats.create_extended_stats&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Performance der Statistik-Erstellung durch Parallelisierung&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Parallelisierung für ein Objekt über Degree-Parameter ("Default is to use parallel degree specified on object"&lt;/li&gt;&lt;li&gt;paralleler Zugriff auf mehrere Objekte: gesteuert über Parameter CONCURRENT&lt;/li&gt;&lt;li&gt;Kombination beider Optionen möglich&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Inkrementelle Erstellung globaler Statistken&lt;/li&gt;&lt;ul&gt;&lt;li&gt;"Typically gathering statistics after a bulk loading data into one partition would causes a full scan of all partitions to gather global table statistics" -&amp;gt; "Extremely time consuming"&lt;/li&gt;&lt;li&gt;Inkremental sorgt dafür, dass nur Partitionen gelsen werden, deren Daten geändert wurden&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;keine Statistiken für&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Volatile Tables: Tabellen mit stark veränderlichen Daten (Queue-Tabellen)&lt;/li&gt;&lt;li&gt;GTT&lt;/li&gt;&lt;li&gt;Intermediate work tables: ETL-Hilfstabellen&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-6266390676812991674?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/6266390676812991674/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2011/10/optimizer-statistics-prasentation.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/6266390676812991674'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/6266390676812991674'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2011/10/optimizer-statistics-prasentation.html' title='Optimizer Statistics Präsentation bei Open World 2011'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-490985381521876171</id><published>2011-10-19T03:11:00.000-07:00</published><updated>2011-10-19T03:11:48.106-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Export'/><title type='text'>Tabellentransfer mit dbms_datapump und DB-Link</title><content type='html'>&lt;a href="http://laurentschneider.com/wordpress/2011/09/duplicate-table-over-database-link.html"&gt;Laurent Schneider&lt;/a&gt; hat vor kurzem eine kleine Demonstration dazu geliefert, wie man einzelne Tabellen mit Hilfe von dbms_datapump transferieren kann, und auf diese Weise auch die abhängigen Elemente (Indizes, Constraints) befördert, die ein CTAS über DB-Link verlieren würde.&lt;br /&gt;&lt;br /&gt;Beim Durchspielen des Beispiels gab's bei mir noch folgende Effekte:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;von 10.2.0.4 nach 11.1.0.7 funktionierte der Transfer problemlos: da der Transfer-Job asynchron läuft, wird die Tabelle zwar sofort angelegt, aber der Datentransfer benötigt anschließend noch einige Zeit, so dass ein SELECT COUNT(*) erst einmal 0 Sätze liefert.&lt;/li&gt;&lt;li&gt;der umgekehrte Weg (von 11.1.0.7 nach 10.2.0.4) lieferte keinen Fehler, aber die Tabelle kam nicht an. Möglicherweise ist da noch ein Kompatiblitätsproblem im Spiel.&lt;/li&gt;&lt;/ul&gt;Auf jeden Fall ein interessantes Feature, das Transfer-Tasks deutlich handhabbarer machen könnte.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-490985381521876171?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/490985381521876171/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2011/10/tabellentransfer-mit-dbmsdatapump-und.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/490985381521876171'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/490985381521876171'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2011/10/tabellentransfer-mit-dbmsdatapump-und.html' title='Tabellentransfer mit dbms_datapump und DB-Link'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-5350647173245080382</id><published>2011-10-19T01:22:00.000-07:00</published><updated>2011-10-19T01:22:14.591-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Statistiken'/><title type='text'>Dynamic Sampling für stark veränderliche Daten</title><content type='html'>Randolf Geist erläutert in seinem &lt;a href="http://oracle-randolf.blogspot.com/2011/10/volatile-data-dynamic-sampling-and.html"&gt;Blog&lt;/a&gt;, in welchen Fällen &lt;i&gt;dynamic sampling&lt;/i&gt; für "highly volatile data" (z.B. in einer &lt;i&gt;global temporary table&lt;/i&gt;) geeigneter ist als eine grundsätzliche Erhebung der Statistiken, und vor allem unter welchen Umständen dynamic sampling nicht ohne Weiteres weiterhilft:&lt;br /&gt;&lt;blockquote&gt;However, there is still a potential problem even when resorting to Dynamic Sampling. If the cursors based on Dynamic Sampling get shared between sessions then they won't be re-optimized even if a GTT in one session is completely different from the one of the session that created the shared cursor previously.&lt;/blockquote&gt;Eine mögliche Lösung solcher Probleme liefert die Verwendung von &lt;i&gt;Row Level Security&lt;/i&gt; (RLS) durch Ergänzung redundanter Prädikate, die dafür sorgen, dass Queries sich textuell unterscheinden (ergänzt wird 1=1; 2=2 oder dergleichen).&lt;br /&gt;&lt;br /&gt;Darüber hinaus werden auch noch die Effekte von Adaptive Cursor Sharing und Cardinality Feedback diskuttiert und - wie beim Herrn Geist üblich - anhand zahlreicher ausführlicher Testfälle überprüft.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-5350647173245080382?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/5350647173245080382/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2011/10/dynamic-sampling-fur-stark.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/5350647173245080382'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/5350647173245080382'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2011/10/dynamic-sampling-fur-stark.html' title='Dynamic Sampling für stark veränderliche Daten'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-6247066222206761125</id><published>2011-10-17T01:40:00.000-07:00</published><updated>2011-10-28T04:39:46.534-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SSAS'/><title type='text'>SSAS 2008 R2 Performance-Guide</title><content type='html'>Der &lt;a href="http://sqlcat.com/sqlcat/b/whitepapers/archive/2011/10/10/analysis-services-2008-r2-performance-guide.aspx"&gt;SSAS-Performance Guide&lt;/a&gt; für Version 2008 R2 ist seit einigen Tagen verfügbar. &lt;a href="http://cwebbbi.wordpress.com/2011/10/11/analysis-services-2008-r2-performance-guide-published/"&gt;Chris Webb&lt;/a&gt; fasst die Bedeutung des Guides prägnant zusammen: "if you are serious about SSAS you need to read it".&lt;br /&gt;&lt;br /&gt;Hier noch eine Sammlung von Punkten, die mir erinnerungswürdig erscheinen (ohne jeden Anspruch auf Vollständigkeit):&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Performance-Vorteile geeigneter Attribute Relationships (S. 11)&lt;/li&gt;&lt;ul&gt;&lt;li&gt;"Cross products between levels in the hierarchy do not need to go through the key attribute. This saves CPU time during queries."&lt;/li&gt;&lt;li&gt;"Aggregations built on attributes can be reused for queries on related attributes. This saves resources during processing and for queries."&lt;/li&gt;&lt;li&gt;"Auto-Exist can more efficiently eliminate attribute combinations that do not exist in the data."&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Flexible vs. Rigid Relationships (S.12)&lt;/li&gt;&lt;ul&gt;&lt;li&gt;"When a change is detected during process in a &lt;b&gt;flexible relationship, all indexes&lt;/b&gt; for partitions referencing the affected dimension (including the indexes for attribute that are not affected) &lt;b&gt;must be invalidated&lt;/b&gt;. This is an expensive operation and may cause Process Update operations to take a very long time. Indexes invalidated by changes in flexible relationships must be rebuilt after a Process Update operation with a Process Index on the affected partitions; this adds even more time to cube processing."&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Reference Dimensions (S. 14)&lt;/li&gt;&lt;ul&gt;&lt;li&gt;können materialisiert werden&lt;/li&gt;&lt;li&gt;Probleme beim ProcessUpdate: "if you run a process update on the intermediate dimension, any changes in the relationships between the outer dimension and the reference will not be reflected in the cube. Instead, the original relationship between the outer dimension and the measure group is retained"&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Large Dimensions (S. 18)&lt;/li&gt;&lt;ul&gt;&lt;li&gt;"If a dimension contains attributes where the total size of the string values (this includes translations) exceeds 4 GB, you will get an error during processing." Für Denali soll das Limit beseitigt werden.&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Partition Slicing (S. 20)&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Auto Slice: "when Analysis Services reads the data during processing, it keeps track of the minimum and maximum attribute DataID reads. These values are used to set the slice when the indexes are built on the partition." + "&lt;b&gt;auto slice typically works best if the data contained in the partition maps to a single attribute value&lt;/b&gt;. When that is the case, the maximum and minimum DataID contained in the slice will be equal and the slice will work efficiently."&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Partition Sizing (S. 22)&lt;/li&gt;&lt;ul&gt;&lt;li&gt;"partition size alone does not have a substantial impact on query speeds"&lt;/li&gt;&lt;li&gt;sollte sich an administrativen Gesichtspunkten orientieren&lt;/li&gt;&lt;li&gt;die &lt;b&gt;BIDS-Warnung vor Partitionen mit mehr als 20M rows ist bedeutungslos&lt;/b&gt;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Relational Data Source Design (S.26ff.)&lt;/li&gt;&lt;ul&gt;&lt;li&gt;"Use a Star Schema for Best Performance"&lt;/li&gt;&lt;li&gt;"Consider Moving Calculations to the Relational Engine"&lt;/li&gt;&lt;li&gt;"Use Views"&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;&amp;nbsp;Query Processor Cache (S. 35)&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Query Context, Session, Context, Global Context: "Even though a query references all three contexts, it will typically use the cache of a single context. This means that on a per-query basis, the query processor must select which cache to use. The query processor always attempts to use the broadly applicable cache depending on whether or not it detects the presence of calculations at a narrower context. &lt;b&gt;If the query processor encounters calculations created at query time, it always uses the query context, even if a query also references calculations from the global context&lt;/b&gt; (there is an exception to this –&lt;br /&gt;queries with query calculated members of the form Aggregate(&lt;set&gt;) do share the session cache)."&lt;/set&gt;&lt;/li&gt;&lt;li&gt;&lt;set&gt;offenbar gibt es &lt;b&gt;sehr viele Fälle, in denen der Global Cache nicht verwendet werden kann&lt;/b&gt; (MDX functions that are locale-dependent; "use of cell security; functions such as UserName, StrToSet, StrToMember, and StrToTuple; or LookupCube functions in the MDX script or in the dimension or cell security definition disable the global cache. That is, just one expression that uses any of these functions or features disables global caching for the entire cube."; visual totals; "Queries that use the subselect syntax (SELECT FROM SELECT) or are based on a session subcube (CREATE SUBCUBE)"; Arbitrary shapes); es bietet sich an, mit dem &lt;b&gt;SQL Profiler&lt;/b&gt; zu prüfen, ob Standard-Excel-Zugriffe den Global Cache verwenden können, oder ob einer der Problemfälle dagegen spricht.&lt;/set&gt;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;&lt;set&gt;Data Retrieval (S.38)&lt;/set&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;&lt;set&gt;Storage Engine (SE) sucht nach Daten in folgender Reihenfolge:&lt;/set&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;&lt;set&gt;SE Cache&lt;/set&gt;&lt;/li&gt;&lt;li&gt;&lt;set&gt;Aggregationen &lt;/set&gt;(I/O from disk oder OS-Cache)&lt;/li&gt;&lt;li&gt;&lt;set&gt;Partitionsdaten (I/O from disk oder OS-Cache)&lt;/set&gt;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;&lt;set&gt;"storage engine cache is &lt;b&gt;also known as the data cache registry&lt;/b&gt; because it is composed of the dimension and measure group caches that are the same structurally"&lt;/set&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;&lt;set&gt;vorhandene Inhalte können aggregiert oder gesplittet werden&lt;/set&gt;&lt;/li&gt;&lt;li&gt;&lt;set&gt;bei Memory-Engpässen wird der Cache geleert&lt;/set&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;set&gt;Aggressive Data Scanning (S. 39): SSAS führt manchmal recht massive Prefetch-Operationen durch (in der Annahme, dass der Anwender die Daten schon noch brauchen wird). Deaktivieren kann man das Prefetching mit "Disable Prefetch = 1" im Connection-String.&lt;/set&gt;&lt;/li&gt;&lt;li&gt;&lt;set&gt;Subspace Computation (S.40ff.): erläutert die Unterschiede zwischen Cell-by-cell evaluation und subspace computation.&amp;nbsp;&lt;/set&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;&lt;set&gt;&amp;nbsp;&lt;/set&gt;Cell-by-cell evaluation: &lt;set&gt;"The 10 cells for [2005, All Products] are each evaluated in turn. For each, the previous year is located, and then the sales value is obtained and then added to the sales for the current year." (bei sparse data wird viel unnötige Arbeit geleistet; außerdem werden Zugriffe unnötig wiederholt)&lt;/set&gt;&lt;/li&gt;&lt;li&gt;&lt;set&gt;"In subspace computation, the engine works its way down an execution tree determining what spaces need to be filled."&lt;/set&gt;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;&lt;set&gt;Expensive vs. Inexpensive Query Plans (S. 42): ein Plan ist expensive, wenn er &lt;/set&gt;Cell-by-cell evaluation enthält: IIf, CASE, and IF functions können expensive query plans hervorrufen. Eine Liste mit Gründen für eine Cell-by-cell evaluation folgt aus Seite 49ff.&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Optimizing MDX (S. 45ff.): liefert diverse Hinweise zur Query-Optimierung (Cache-Effekte ausschalten; SQL Profiler nutzen; Unterscheidung zwischen SE und FE Events; binäre Vereinfachung von Queries etc.) und auch einige wichtige Links. Hier nur die Punkte, diemir halbwegs neu waren:&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Avoid Assigning Nonnull Values to Otherwise Empty Cells (S. 50): leuchtet ein, denn SSAS "is very efficient at using sparsity of the data to improve performance. Adding calculations with nonempty values replacing empty values does not allow Analysis Services to eliminate these rows."&lt;/li&gt;&lt;li&gt;Sparse/Dense Considerations with “expr1 * expr2” Expressions (S. 51): die Expression mit der höheren Anzahl von NULLs sollte vorne stehen: entspricht dem Vorgehen bei Nested Loops Joins, wo ebenfalls die kleinere Menge die Schleife treiben sollte.&lt;/li&gt;&lt;li&gt;IIF-Optimierung mit den Hints EAGER und STRICT (S. 53).&lt;/li&gt;&lt;li&gt;NON_EMPTY_BEHAVIOR: in 2008 in vielen Fällen nicht mehr nützlich (= wird oft ignoriert), und manchmal sogar ein Problem ("Eliminate it from the MDX script and add it back after performance testing demonstrates improvement")&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;&amp;nbsp;Aggregations (S. 60ff.)&lt;/li&gt;&lt;ul&gt;&lt;li&gt;&amp;nbsp;unnötige Aggregationen schädigen den Cache: "adding unnecessary aggregations can worsen query performance because the rare hits move the aggregation into the file cache at the cost of moving something else out"; außerdem: "there is a direct correlation between the number of aggregations and the duration for the Analysis Services storage engine to parse them"&lt;/li&gt;&lt;li&gt;&amp;nbsp;Aggregations-Zugriffe werden im Profiler durch das "Get Data From Aggregation event" ausgewiesen&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Scale-Out (S. 69): Verteilung auf mehrere Server; z.B. zur Vermeidung des Blockierens durch langlaufende Queries.&lt;/li&gt;&lt;li&gt;Tuning Processing Performance (S. 70ff.)&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Dimension Processing &lt;/li&gt;&lt;ul&gt;&lt;li&gt;ProcessUpdate (S. 76)&amp;nbsp;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;erfordert Neuaufbau von flexible aggregations: "Note that ProcessUpdate drops invalid aggregations and indexes, requiring you to take action to rebuild the aggregations in order to maintain query performance. However, flexible aggregations are dropped only if a change is detected."&lt;/li&gt;&lt;li&gt;kann sehr teuer sein: "When ProcessUpdate runs, it must walk through the partitions that depend on the dimension. For each partition, all indexes and aggregation must be checked to see whether they require updating. On a cube with many partitions, indexes, and aggregates, this can take a very long time. Because this dependency walk is expensive, ProcessUpdate is often the most expensive of all processing operations on a well-tuned system, dwarfing even large partition processing commands."&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;ProcessAdd (S. 77):&amp;nbsp;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;"typically runs much faster than ProcessUpdate."&lt;/li&gt;&lt;li&gt;mit Default Konfiguration gibt's Fehlermeldungen duplicate key beim Processing ("caused by the addition of non-key properties that already exist in the dimension": Anpassung der Fehlerkonfiguration erforderlich)&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;ul&gt;&lt;ul&gt;&lt;li&gt;Tuning&lt;/li&gt;&lt;ul&gt;&lt;li&gt; Reduzierung der Dimensionsattribute&lt;/li&gt;&lt;li&gt;Verzicht auf Bitmap Indexes&lt;/li&gt;&lt;li&gt;ByTable Processing: liefert notwendigerweise duplicate key Fehler&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;li&gt;Splitting Processing Index and Process Data (S.84): wird immer noch empfohlen&lt;/li&gt;&lt;ul&gt;&lt;ul&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-6247066222206761125?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/6247066222206761125/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2011/10/ssas-2008-r2-performance-guide.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/6247066222206761125'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/6247066222206761125'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2011/10/ssas-2008-r2-performance-guide.html' title='SSAS 2008 R2 Performance-Guide'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-4447553459574697606</id><published>2011-10-17T01:06:00.000-07:00</published><updated>2011-10-17T01:06:23.763-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ETL'/><title type='text'>Die Zukunft des OWB</title><content type='html'>Dani Snider von Trivadis gibt eine kurze &lt;a href="http://blog.trivadis.com/b/danischnider/archive/2011/10/10/oracle-openworld-future-of-owb.aspx"&gt;Zusammenfassung&lt;/a&gt; zur aktuellen strategischen Planung der Oracle-ETL-Landschaft. Offenbar hat der &lt;i&gt;Oracle Warehouse Builder&lt;/i&gt; (OWB) keine Zukunft mehr, was sich allerdings schon seit einiger Zeit &lt;a href="http://martinpreiss.blogspot.com/2011/01/oracle-etl.html"&gt;andeutete&lt;/a&gt;:&lt;br /&gt;&lt;blockquote&gt;OWB 11g Release 2 will be the final release of Oracle Warehouse Builder. No major enhancements are planned for this tool. Support, patches and bug fixes will still be delivered for the next years. OWB 11.2 will be supported for the whole lifecycle of Oracle Database 12c, so there is no hurry to switch to ODI as soon as possible. But the strategic ETL product of Oracle is ODI, and new customers are recommended to use this tool.&lt;/blockquote&gt;Dani Snider sieht in diesem Zusammenhang vor allem zwei offene Punkte:&lt;br /&gt;&lt;ul&gt;&lt;li&gt; Eine kurzfrsitige Migration in Richtung ODI ist mangels Toolunterstützung offenbar nicht angeraten.&lt;/li&gt;&lt;li&gt;Abgesehen davon sind die Lizenzkosten für den ODI relativ hoch, was ein Anlaß zur Verwendung von ETL-Tools anderer Anbieter sein könnte ("There are several good open source ETL products on the market.") &lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-4447553459574697606?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/4447553459574697606/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2011/10/die-zukunft-des-owb.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/4447553459574697606'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/4447553459574697606'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2011/10/die-zukunft-des-owb.html' title='Die Zukunft des OWB'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-1711223510884817280</id><published>2011-09-28T01:48:00.000-07:00</published><updated>2011-09-28T03:15:15.545-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Partitioning'/><category scheme='http://www.blogger.com/atom/ns#' term='Index'/><title type='text'>Partition Exchange + Indizierung</title><content type='html'>Über &lt;i&gt;Partition Exchange&lt;/i&gt; hatte ich &lt;a href="http://martinpreiss.blogspot.com/2011/08/partition-exchange.html"&gt;hier&lt;/a&gt; vor einiger Zeit etwas geschrieben, musste mich dieser Tage aber noch mal etwas ernsthafter mit dem Thema beschäftigen, und kam dabei zu folgenden Ergebnissen:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Wenn man im "ALTER TABLE ... EXCHANGE PARTITION ... WITH TABLE ..." keine Klausel "INCLUDING INDEXES" angibt, dann werden alle auf der Austauschtabelle aufgebauten Indizes beim Exchange UNUSABLE.&lt;/li&gt;&lt;li&gt; Beim Aufbau von Indizes muss man den Grad der COMPRESSION berücksichtigen, da man sonst auf "ORA-28665: Tabelle und Partition müssen dasselbe Komprimierungsattribut haben" trifft. Der Fehlertext ist somit also etwas unpräzise, da auch Indizes berücksichtigt werden müssen.&lt;/li&gt;&lt;/ul&gt;Und noch eine harmlose Ergänzung: zum Monitoring des Stands der Index-Erzeugung kann man neben dem SQL-Monitor, v$session_longopsund den workare-Views auch noch dba_segments heranziehen:&lt;br /&gt;&lt;br /&gt;&lt;div class="codesnippet"&gt;&lt;pre&gt;select *&lt;br /&gt;  from dba_segments&lt;br /&gt; where segment_type = 'TEMPORARY';&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;liefert Informationen zur Größe des im Aufbau befindlichen Index, der zunächst als temporäres Objekt mit einer technischen Id erzeugt wird, ehe daraus dann das permanente Segment wird.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-1711223510884817280?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/1711223510884817280/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2011/09/partition-exchange-indizierung.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/1711223510884817280'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/1711223510884817280'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2011/09/partition-exchange-indizierung.html' title='Partition Exchange + Indizierung'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-5240753405900991934</id><published>2011-09-28T01:35:00.000-07:00</published><updated>2011-09-28T01:35:04.071-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Datenmodell'/><category scheme='http://www.blogger.com/atom/ns#' term='RAC'/><title type='text'>Iggy Fernandez über DB-Design und Features</title><content type='html'>Die Überschriften der Einträge hier werden allmählich unübersichtlicher ...&lt;br /&gt;&lt;br /&gt;Iggy Fernandez hat zuletzt einige interessante Artikel geschrieben, die ich hier summarisch verlinke:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://iggyfernandez.wordpress.com/2011/09/04/lesson-1-of-40-physical-database-design-for-oracle-database-necessity-and-definition/"&gt;Lesson 1 of 40: Physical Database Design for Oracle Databases: Necessity and Definition&lt;/a&gt; mit einer recht knappen Unterscheidung von logischem und phsyikalischem DB-Design ("Logical database design is the process of designing normalized database tables." vs. "Physical database design is the process of designing indexes, partitions, clusters, and materialized views.")&lt;/li&gt;&lt;li&gt;&lt;a href="http://iggyfernandez.wordpress.com/2011/09/13/lesson-2-of-40-physical-database-design-for-oracle-databases-non-necessity/"&gt;Lesson 2 of 40: Physical Database Design for Oracle Databases: Non-Necessity?&lt;/a&gt; behandelt die Frage, ob man sich angesichts niedriger Hardwarepreise die Mühe der Zugriffsoptimierung sparen kann. Die These wurde dieser Tage von Bert Scalzo vertreten (“So, with such cheap hardware, it might be a wiser business bet to throw hardware at some solutions sooner than was done in the past.”), wobei Jonathan Lewis bereits darauf hinwies, dass das wichtigste Wort in diesem Satz das "sooner" ist. Die meisten extremen Performance-Probleme, denen ich begegne, haben erst mal recht wenig mit der Hardware-Leistung zu tun und sehr viel mit dem Design.&lt;/li&gt;&lt;li&gt;&lt;a href="http://iggyfernandez.wordpress.com/2011/09/24/unconventional-wisdom-do-we-probably-need-rac-exadata-oracle-database-12c-mysql-certification-and-oracle-user-groups/"&gt;Unconventional Wisdom: Do we probably need RAC, Exadata, Oracle Database 12c, MySQL, certification, and Oracle user groups?&lt;/a&gt; verweist auf Mogens Norgaards älteren Artikel zur Frage, wer eigentlich RAC brauche, die dort mit einem klaren "(fast) niemand" beantwortet wurde - und beschäftigt sich im Anschluß daran mit weiteren technischen und Marketing-Themen, deren praktische Relevanz begutachtet wird.&lt;/li&gt;&lt;/ul&gt;Wenn der Herr Fernandez seine Drohung wahr macht und tatsächlich 40 Lessons liefert, werde ich mir die Links aber vermutlich irgendwann sparen ... &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-5240753405900991934?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/5240753405900991934/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2011/09/iggy-fernandez-uber-db-design-und.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/5240753405900991934'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/5240753405900991934'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2011/09/iggy-fernandez-uber-db-design-und.html' title='Iggy Fernandez über DB-Design und Features'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-486408766000498745</id><published>2011-09-26T12:18:00.000-07:00</published><updated>2011-09-26T12:18:51.867-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SQL'/><title type='text'>EXISTS im SELECT</title><content type='html'>&lt;a href="http://rwijk.blogspot.com/2011/09/exists.html"&gt;Rob van Wijk&lt;/a&gt;, dessen Blog ich - wie ich vielleicht schon mal erwähnt habe - sehr schätze, hat mal wieder etwas Interessantes angesprochen: man kann EXISTS nicht nur im WHERE, sondern in einer &lt;i&gt;searched case expression&lt;/i&gt; auch im SELECT verwenden, was in bestimmten Fällen effizienter sein kann als ein entsprechender OUTER JOIN. Wie immer beim Herrn van Wijk gibt's aussagekräftige Beispiele und eine einleuchtende Erklärung des Verhaltens.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-486408766000498745?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/486408766000498745/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2011/09/exists-im-select.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/486408766000498745'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/486408766000498745'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2011/09/exists-im-select.html' title='EXISTS im SELECT'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-1942844622453948763</id><published>2011-09-25T08:23:00.000-07:00</published><updated>2011-09-25T08:23:33.602-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Index'/><title type='text'>Index Rebuilds und der Clustering Factor</title><content type='html'>&lt;a href="http://richardfoote.wordpress.com/2011/09/25/rebuilding-indexes-and-the-clustering-factor-solution-move-on/"&gt;Nächstes Quiz des Herrn Foote&lt;/a&gt;, diesmal zur Frage, wann ein Index Rebuild den &lt;i&gt;Clustering Factor &lt;/i&gt;ändern kann. Im Grunde ist die Antwort: nie, aber es gibt doch ein paar Spezialfälle, die man als Ausnahmen von der Regel betrachten kann. Grundsätzlich gilt:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;So for an index rebuild to actual have an impact on the CF on an index, means either the rows in the table needs to change or the order of the index entries needs to change.&lt;br /&gt;However, when we typically rebuild an index, it has no impact at all on the table and so can’t possibly change&amp;nbsp;the order of the rows there. Additionally, no matter how fragmented or inefficient the index structure might be, an index rebuild doesn’t change the &lt;strong&gt;order&lt;/strong&gt; of the index entries either&amp;nbsp;as they’re always sorted within the index in the order of the indexed columns.&lt;/blockquote&gt;Die Ausnahmen der&amp;nbsp; Regel sind Indizes, die von REVERSE auf NOREVERSE oder umgekehrt umgestellt werden - was aus meiner Sicht aber eigentlich etwas Anderes ist als ein einfacher Neuaufbau. Ein anderer Spezialfall wäre die Definitionsänderung eines FBI - aber auch das ist kein einfaches Rebuild. Damit kann man für alle praktischen Fälle wohl doch bei der Regel bleiben, dass nur ein Neuaufbau der Tabelle den &lt;i&gt;Clustering Factor&lt;/i&gt; eines Index ändern kann. &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-1942844622453948763?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/1942844622453948763/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2011/09/index-rebuilds-und-der-clustering.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/1942844622453948763'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/1942844622453948763'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2011/09/index-rebuilds-und-der-clustering.html' title='Index Rebuilds und der Clustering Factor'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-8957762452797645712</id><published>2011-09-23T09:28:00.000-07:00</published><updated>2011-09-23T09:29:35.088-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Releases'/><title type='text'>Oracle 11.2.0.3</title><content type='html'>&lt;a href="http://structureddata.org/2011/09/23/11-2-0-3-patch-set-for-oracle-database-server/"&gt;Greg Rahn&lt;/a&gt; weist darauf hin, dass das Patchset 11.2.0.3 für diverse Platformen veröffentlicht wurde. Laut &lt;a href="http://download.oracle.com/docs/cd/E11882_01/server.112/e22487/chapter1_11203.htm"&gt;New Feature Guide&lt;/a&gt; liegen die Verbesserungen vor allem in den Bereichen ACFS, XML und OWB.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-8957762452797645712?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/8957762452797645712/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2011/09/oracle-11203.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/8957762452797645712'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/8957762452797645712'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2011/09/oracle-11203.html' title='Oracle 11.2.0.3'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-2168304582531586732</id><published>2011-09-23T05:56:00.000-07:00</published><updated>2011-09-23T06:23:35.503-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Recovery'/><title type='text'>Recovery Area</title><content type='html'>Uwe Hesse erläutert in seinem &lt;a href="http://uhesse.wordpress.com/2011/09/22/the-recovery-area-why-it-is-recommended/"&gt;Blog&lt;/a&gt; sehr ausführlich, warum eine Recovery Area empfehlenswert ist. Wenn ich mich mal wieder als DBA ausgebe, wäre das ein Thema, das intensivere Beschäftigung verdiente.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-2168304582531586732?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/2168304582531586732/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2011/09/recovery-area.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/2168304582531586732'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/2168304582531586732'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2011/09/recovery-area.html' title='Recovery Area'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-4173440309161244392</id><published>2011-09-23T01:22:00.000-07:00</published><updated>2011-09-23T01:28:45.439-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Partitioning'/><category scheme='http://www.blogger.com/atom/ns#' term='Index'/><title type='text'>Rebuild Partitioned Index</title><content type='html'>Da ich die Syntax mit schöner Regelmäßigkeit anderswo suche, schreibe ich sie mal hier auf: um eine Index-Partition UNUSABLE zu setzen bzw. wieder neu aufzubauen, kann man folgende Kommandos verwenden:&lt;br /&gt;&lt;br /&gt;&lt;div class="codesnippet"&gt;&lt;pre&gt;alter index ... modify partition ... unusable;&lt;br /&gt;alter index ... rebuild partition ...;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;Alternativ kann man auch alle lokalen Indizes einer Partition auf einmal auf UNUSABLE setzen bzw. neu aufbauen:&lt;br /&gt;&lt;br /&gt;&lt;div class="codesnippet"&gt;&lt;pre&gt;alter index ... modify partition ... unusable local indexes;&lt;br /&gt;alter index ... modify partition ... rebuild unusable local indexes;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;Ein kleines Beispiel zum Thema liefert &lt;a href="http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:749601300346452652"&gt;Tom Kyte&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Leider kann man einen als UNIQUE definierten Index vor einem Massendaten-Ladevorgang nicht über diesen Weg deaktivieren, um ihn später wieder aufzubauen, da das INSERT dann gegen einen ORA-01502 ("index 'string.string' or partition of such index is in unusable state") läuft - Details zu diesem Problem finden sich &lt;a href="http://martinpreiss.blogspot.com/2011/05/unusable-indexes.html"&gt;hier&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-4173440309161244392?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/4173440309161244392/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2011/09/rebuild-partitioned-index.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/4173440309161244392'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/4173440309161244392'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2011/09/rebuild-partitioned-index.html' title='Rebuild Partitioned Index'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-6431208976416913437</id><published>2011-09-22T11:56:00.000-07:00</published><updated>2011-09-22T11:56:56.708-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tablespaces'/><title type='text'>Lebenszeit von Tablespace-Quotas</title><content type='html'>In Stefan Oehrlis &lt;a href="http://www.oradba.ch/2011/09/tablespace-quotas-are-forever/"&gt;Blog&lt;/a&gt; findet sich ein interessanter Hinweis: wenn man einen Tablespace löscht und später wieder einen gleichnamigen TS anlegt, dann werden Quotas, die für den alten TS galten auch wieder für den neuen wirksam. Klingt für mich wie eine fragwürdige Konstruktion.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-6431208976416913437?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/6431208976416913437/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2011/09/lebenszeit-von-tablespace-quotas.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/6431208976416913437'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/6431208976416913437'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2011/09/lebenszeit-von-tablespace-quotas.html' title='Lebenszeit von Tablespace-Quotas'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-118581680934545041</id><published>2011-09-21T08:36:00.000-07:00</published><updated>2011-09-21T08:36:01.155-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Trace'/><title type='text'>dbms_xplan.display_cursor und plan statistics</title><content type='html'>Kyle Haileys Blog ist auch eine dieser Ressourcen, aus denen man eigentlich jeden Beitrag verlinken kann... Diesmal liefert der Herr Hailey &lt;a href="http://dboptimizer.com/2011/09/20/display_cursor/"&gt;eine detaillierte Beschreibung der display_cursor-Routine&lt;/a&gt; aus dbms_xplan, erläutert den Hint gather_plan_statistics und weitere Möglichkeiten, die erweiterten &lt;i&gt;row source execution stats&lt;/i&gt; zu aktivieren, und liefert schließlich eine Query, mit der man aus v$sql_plan_statistics_all die Hinweise auf massive Abweichungen zwischen E-Rows und A-Rows komfortable visualisieren kann.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-118581680934545041?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/118581680934545041/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2011/09/dbmsxplandisplaycursor-und-plan.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/118581680934545041'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/118581680934545041'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2011/09/dbmsxplandisplaycursor-und-plan.html' title='dbms_xplan.display_cursor und plan statistics'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-1038277679605026088</id><published>2011-09-21T04:17:00.000-07:00</published><updated>2011-09-21T04:17:34.257-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SSAS'/><title type='text'>SSAS Maestros</title><content type='html'>Microsoft hat eine erste Gruppe von SSAS-Spezailisten mit dem Adelsprädikat eines &lt;a href="http://sqlcat.com/sqlcat/b/technicalnotes/archive/2011/09/19/announcing-the-first-wave-of-ssas-maestros.aspx"&gt;SSAS-Maestros&lt;/a&gt; ausgezeichnet. Bei der Titelgebung solcher Auszeichnungen scheint Kreativität gefragt zu sein - mal sehen, wer als erster seine Erzmagier, Diakone und Kardinäle benennt. Immerhin liefert mir der Beitrag ein oder zwei neue Blogs für meinen Reader.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-1038277679605026088?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/1038277679605026088/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2011/09/ssas-maestros.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/1038277679605026088'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/1038277679605026088'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2011/09/ssas-maestros.html' title='SSAS Maestros'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-8602138326352983517</id><published>2011-09-19T12:58:00.000-07:00</published><updated>2011-09-19T12:58:36.640-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Trace'/><category scheme='http://www.blogger.com/atom/ns#' term='Statistiken'/><title type='text'>Abhängigkeit von Features vom STATISTICS_LEVEL</title><content type='html'>Christian Antognini weist in seinem &lt;a href="http://antognini.ch/2011/09/impact-of-statistics_level-on-cardinality-feedback-and-adaptive-cursor-sharing/"&gt;Blog&lt;/a&gt; auf die Abhängigkeit der Erhebung diverser elaborierter Statistiken vom STATISTICS_LEVEL hin. Neben den in V$STATISTICS_LEVEL aufgeführten Statistiken sind seinen Beoachtungen nach auch &lt;i&gt;Cardinality Feedback&lt;/i&gt; und &lt;i&gt;Adaptive Cursor Sharing&lt;/i&gt; vom STATISTICS_LEVEL abhängig.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-8602138326352983517?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/8602138326352983517/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2011/09/abhangigkeit-von-features-vom.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/8602138326352983517'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/8602138326352983517'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2011/09/abhangigkeit-von-features-vom.html' title='Abhängigkeit von Features vom STATISTICS_LEVEL'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-1929613050238283665</id><published>2011-09-17T14:32:00.000-07:00</published><updated>2011-12-25T02:18:31.817-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Blogs'/><title type='text'>Deutschsprachige Oracle-Webseiten</title><content type='html'>Hier mal der Versuch, jene Liste von deutschsprachigen Oracle-Ressourcen zu erstellen, die ich schon häufiger anderswo gesucht habe:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;&lt;b&gt;Blogs&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Blogs &lt;/b&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://sql-plsql-de.blogspot.com/"&gt;SQL und PL/SQL in Oracle&lt;/a&gt;: Carsten Czarskis lesenswertes Blog mit z.T. sehr ausführlichen technischen Erläuterungen zu weniger bekannten DB-Features.&lt;/li&gt;&lt;li&gt;&lt;a href="http://blog.oraconsult.de/"&gt;oraconsult Oracle Blog&lt;/a&gt;: Blog von Felix Castillo Sanchez zu Performance-Themen.&amp;nbsp;&lt;/li&gt;&lt;li&gt;&lt;a href="http://oraculix.wordpress.com/"&gt;Oraculix&lt;/a&gt;: Blog von Uwe Küchler.&lt;/li&gt;&lt;li&gt;&lt;a href="http://ora-sql-plsql.blogspot.com/"&gt;Oracle SQL und PL/SQL&lt;/a&gt;: Blog von Thomas Uhren mit mathematischem und statistischem Schwerpunkt.&amp;nbsp;&lt;/li&gt;&lt;li&gt;&lt;a href="http://danirey.wordpress.com/"&gt;Dani Rey's Oracle Stuff&lt;/a&gt;: Blog von Dani Rey (die Mehrzahl der Artikel ist englischsprachig - dabei aber sehr interessant).&amp;nbsp;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.christian-klisch.de/category/computer/datenbank"&gt;My Technical Blog&lt;/a&gt;: von Christian Klisch&lt;/li&gt;&lt;li&gt;&lt;a href="http://blog.red-database-security.de/"&gt;Alexander Kornbrust Oracle Security Blog dt.&lt;/a&gt;: deutschsprachiger Blog von Alexander Kornbrust zu Security-Themen. Die Inhalte weichen von denen des &lt;a href="http://blog.red-database-security.com/"&gt;englischsprachigen Blogs&lt;/a&gt; des Herrn Kornbrust ab.&lt;/li&gt;&lt;li&gt;&lt;a href="http://oracle-text-de.blogspot.com/"&gt;Oracle TEXT: Tipps, Tricks, Best Practice&lt;/a&gt;: Blog zu Oracle-Text-Themen von Carsten Czarski und Ulrike Schwinn.&lt;/li&gt;&lt;li&gt;&lt;a href="http://oracle-spatial.blogspot.com/"&gt;Geodaten für Alle: Oracle Spatial&lt;/a&gt;: noch ein Blog, an dem der Herr Czarski mitarbeitet - diesmal zum Thema Oracle Spatial.&lt;/li&gt;&lt;li&gt;&lt;a href="http://htmldb-de.blogspot.com/"&gt;Rund um Oracle APEX&lt;/a&gt;: Apex-Blog von Bernhard Fischer-Wasels.&lt;/li&gt;&lt;li&gt;&lt;a href="http://friedhold-matz.blogspot.com/"&gt;Friedhold's Oracle World&lt;/a&gt;: Blog von Friedhold Matz mit Schwerpunkt Oracle Maps.&lt;/li&gt;&lt;li&gt;&lt;a href="http://bbroehl.wordpress.com/"&gt;Björn's Weblog&lt;/a&gt;: Blog des Oracle Ace Director Björn Bröhl (aktuell Trivadis, früher Opitz).&lt;/li&gt;&lt;li&gt;&lt;a href="http://streetkiter.wordpress.com/"&gt;Streetkiter&lt;/a&gt;: Blog von Johannes Ahrends.&lt;/li&gt;&lt;li&gt;&lt;a href="http://mpaege.wordpress.com/"&gt;mpaege&lt;/a&gt;: Blog von Michael Paege (Opitz).&lt;/li&gt;&lt;li&gt;&lt;a href="http://christiantrieb.blogspot.com/"&gt;ORACLE Datenbank&lt;/a&gt;: Blog von Christian Trieb (Vizepräsident der DOAG) mit sehr vielen Veranstaltungs-Hinweisen und DOAG-Informationen.&lt;/li&gt;&lt;li&gt;&lt;a href="http://sven.svenvetter.com/"&gt;Sven's Technik-Blog&lt;/a&gt;: Blog von Sven Vetter (Trivadis).&lt;/li&gt;&lt;li&gt;&lt;a href="http://talk2gerd-de.blogspot.com/"&gt;Talk2Gerd&lt;/a&gt;: Blog von Gerd Volberg.&lt;/li&gt;&lt;li&gt;&lt;a href="http://blog.doag.org/"&gt;DOAG BLOG Aggregator&lt;/a&gt;: ein Aggregator, der diverse der oben genannten Blogs zusammenfasst.&lt;/li&gt;&lt;li&gt;&lt;a href="http://germanoracleblogaggregator.blogspot.com/"&gt;German Oracle Blog Aggregator&lt;/a&gt;: ein Blog-Aggregator von Norbert Henz, der ebenfalls einige der bereits genannten Blogs - nun ja: aggregiert.&lt;/li&gt;&lt;li&gt;&lt;a href="http://blog.trivadis.com/"&gt;Trivadis&lt;/a&gt;: Gruppen-Blog der Trivadis Mitarbeiter zu Oracle, SQL Server, Sharepoint und vielen anderen Themen. &lt;/li&gt;&lt;/ul&gt;&lt;b&gt;Foren&lt;/b&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://entwickler-forum.de/forumdisplay.php?f=44"&gt;Oracle - Entwicklerforum&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.tutorials.de/relationale-datenbanksysteme/"&gt;Tutorials.de - Relationale Datenbanksysteme&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.held-informatik.de/forum/"&gt;Held Informatik Forum&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="https://www.xing.com/net/oracle/forums"&gt;XING Oracle-Forum&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;b&gt;Webseiten&lt;/b&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.doag.org/de/wissen.html"&gt; DOAG&lt;/a&gt;:die Webseite der Deutschen ORACLE-Anwendergruppe.&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.muniqsoft.de/tipps.htm"&gt;MuniQSoft&lt;/a&gt;: Tipps und Tricks der Münchener Beratungsfirma der Herren Wesnitzer und Patzwahl. Vor einigen Jahren gab's hier auch ein recht lebendiges Oracle-Forum.&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.opitz-consulting.com/veroeffentlichungen/whitepaper.php"&gt;Opitz Consulting&lt;/a&gt;: Eine Sammlung von Whitepapers.&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.held-informatik.de/tipps-tricks"&gt;Held Informatik&lt;/a&gt;: Tipps und Tricks.&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.durben.de/html/truncate_table_in_oracle_daten.html"&gt;Tipps und Tricks für Oracle Datenbanken&lt;/a&gt;: Tipps und Tricks von Ralf Durben.&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.oracle.com/webfolder/technetwork/de/community/platform/index.html%20"&gt;Communities der Business Unit ST-PCM (Server Technology - Platforms Competition Modernization)&lt;/a&gt;: Eine Liste von Communities, die von Mitarbeitern von Oracle-Deutschland geleitet werden.&lt;/li&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.oracle.com/webfolder/technetwork/de/community/dbadmin/rss.xml"&gt;Oracle DBA Community&lt;/a&gt;: technische Artikel von diversen Mitarbeitern von Oracle Deutschland.&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.oracle.com/webfolder/technetwork/de/community/apex/index.html"&gt;Oracle APEX Community&lt;/a&gt;: Neuigkeiten, Tipps und Links zu APEX.&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.oracle.com/webfolder/technetwork/de/community/dwh/index.html"&gt;Oracle DWH Community&lt;/a&gt;: über die &lt;a href="http://www.oracledwh.de/index.php?dir=./downloads"&gt;Download-Seite&lt;/a&gt; kommt man zu diversen Vorträgen und Artikeln.&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;&lt;a href="http://www.datenbank-sql.de/index.htm"&gt;Oracle SQL Tutorial&lt;/a&gt;: ein einfaches SQL-Tutorial von Taktum Software.&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.martinbulinski.de/ORACLE/PLSQL-Tutorial/"&gt;PL/SQL Tutorial&lt;/a&gt;: ein recht umfangreiches PL/SQL Tutorial von Martin Bulinski. Die Webseite enthält auch noch weitere Artikel zu PL/SQL, SQL und zur DB-Administration.&lt;/li&gt;&lt;li&gt;&lt;a href="http://use-the-index-luke.com/de"&gt;Use the Index, Luke!&lt;/a&gt;: Markus Winands kenntnisreiche "Gratis-Anleitung zu SQL Indizierung und SQL Tuning für Entwickler" (deutsch und englisch).&lt;/li&gt;&lt;ul&gt;&lt;/ul&gt;&lt;/ul&gt;Die Liste bleibt relativ kurz, denn die meisten renommierten deutschsprachigen Oracle-Spezialisten schreiben englischsprachige Blogs. Extrem alte Webseiten, die offensichtlich nicht mehr aktualisiert werden, habe ich nicht berücksichtigt.&lt;br /&gt;&lt;br /&gt;Bisher ist die Liste eher eine Draft-Version, die sich sicher noch erweitern lässt - wenn jemand andere Seiten kennt, die hier fehlen, würde ich mich über entsprechende Kommentare freuen.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Nachtrag 19.09.2011&lt;/b&gt;: ergänzt um vier Links aus dem Kommentar von Andreas und um den Hinweis auf die Oracle Communities aus Claus Jandauschs Kommentar.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-1929613050238283665?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/1929613050238283665/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2011/09/deutschsprachige-oracle-webseiten.html#comment-form' title='4 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/1929613050238283665'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/1929613050238283665'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2011/09/deutschsprachige-oracle-webseiten.html' title='Deutschsprachige Oracle-Webseiten'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-381832874842407203</id><published>2011-09-17T13:14:00.000-07:00</published><updated>2011-09-26T12:28:23.507-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Data Warehouse'/><category scheme='http://www.blogger.com/atom/ns#' term='Datenmodell'/><title type='text'>Data Warehouse Architektur</title><content type='html'>Thomas Kejser formuliert in seinem &lt;a href="http://blog.kejser.org/2011/08/30/the-big-picture-edwdw-architecture/"&gt;Blog&lt;/a&gt; einen interessanten Architekturvorschlag für &lt;i&gt;Data Warehouses&lt;/i&gt;, der für mich wie eine behutsame Weiterentwicklung der Kimballschen Überlegungen aussieht. Man findet dort auch noch einen &lt;a href="http://forum.kimballgroup.com/t362-data-vault-v-s-dimensional-model"&gt;Link&lt;/a&gt; zum Kimball Forum, wo die Frage von Normalisierung/Denormalisierung im DWH-Kontext offenbar immer noch als Glaubenskrieg diskutiert wird.&lt;br /&gt;&lt;br /&gt;Ebenfalls aus dem Microsoft-BI-Kosmos stammen die Überlegungen, die der&lt;i&gt; &lt;a href="http://dwjunkie.wordpress.com/2011/09/26/data-warehouse-reference-architecture/"&gt;Data Warehouse Junkie&lt;/a&gt;&lt;/i&gt; Marcel Franke in seinem Blog entwickelt.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-381832874842407203?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/381832874842407203/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2011/09/data-warehouse-architektur.html#comment-form' title='2 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/381832874842407203'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/381832874842407203'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2011/09/data-warehouse-architektur.html' title='Data Warehouse Architektur'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-6329590698822579657</id><published>2011-09-17T12:49:00.000-07:00</published><updated>2011-09-17T12:49:19.432-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Trace'/><category scheme='http://www.blogger.com/atom/ns#' term='Security'/><title type='text'>ORADEBUG als Sicherheitsrisiko</title><content type='html'>Alexander Kornbrust erläutert in seinem &lt;a href="http://blog.red-database-security.com/2011/09/17/disable-auditing-and-running-os-commands-using-oradebug/"&gt;Blog&lt;/a&gt;, welche - im Hinblick auf Security-Fragen gefährlichen - Optionen ORADEBUG zur Verfügung stellt.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-6329590698822579657?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/6329590698822579657/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2011/09/oradebug-als-sicherheitsrisiko.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/6329590698822579657'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/6329590698822579657'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2011/09/oradebug-als-sicherheitsrisiko.html' title='ORADEBUG als Sicherheitsrisiko'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-2227726725085989851</id><published>2011-09-16T07:08:00.000-07:00</published><updated>2011-09-19T00:55:16.591-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Lock'/><title type='text'>Row Cache Lock</title><content type='html'>Dieser Tage ist mir folgendes Phänomen begegnet: zu einer großen Tabelle existierte ein Index für die Spalten des Primary Keys, wobei der Primary Key selbst disabled war. Ohne intensiver darüber nachzudenken, hatte ich angenommen, dass die Aktivierung des PKs sich darauf beschränken würde, zu prüfen, ob ein passender Index exisitiert - aber offenbar ist anschließend noch mehr zu tun. Meine Vermutung war, dass ein weiterer FTS stattfinden müsste, aber ein Blick in v$session_longops konnte das nicht bestätigen. Genauer gesagt konnte v$session_longops gar nichts bestätigen oder widerlegen, da die Abfrage von der Session, in der die PK-Aktivierung lief, geblockt wurde. Das Verhalten lässt sich mit einem einfachen Test stabil reproduzieren (hier in 11.1.0.7):&lt;br /&gt;&lt;br /&gt;&lt;div class="codesnippet"&gt;&lt;pre&gt;-- Löschung und Neuanlage einer Testtabellen mit 10M rows&lt;br /&gt;drop table big_t purge;&lt;br /&gt;&lt;br /&gt;create table big_t&lt;br /&gt;as&lt;br /&gt;with&lt;br /&gt;base_data&lt;br /&gt;as&lt;br /&gt;(&lt;br /&gt;select rownum id1&lt;br /&gt;  from dual&lt;br /&gt;connect by level &amp;lt;= 1000000&lt;br /&gt;)&lt;br /&gt;,&lt;br /&gt;mult&lt;br /&gt;as&lt;br /&gt;(&lt;br /&gt;select rownum id2&lt;br /&gt;  from dual&lt;br /&gt;connect by level &amp;lt;= 10&lt;br /&gt;)&lt;br /&gt;select rownum id&lt;br /&gt;     , 'aaaaaaaaa' col2&lt;br /&gt;  from mult&lt;br /&gt;     , base_data;&lt;br /&gt;&lt;br /&gt;alter table big_t modify id not null;&lt;br /&gt;&lt;br /&gt;create index big_t_idx on big_t(id);&lt;br /&gt;&lt;br /&gt;alter table big_t add constraint big_t_pk primary key (id) disable;&lt;br /&gt;&lt;br /&gt;alter table big_t enable constraint big_t_pk;&lt;br /&gt;&lt;br /&gt;Tabelle wurde geändert.&lt;br /&gt;&lt;br /&gt;Abgelaufen: 00:00:17.26&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;Ein gleichzeitiger Zugriff einer zweiten Session auf v$session_longops (nicht aber auf viele andere v$-Views) wird blockiert, und in einer dritten Session kann man dazu in v$session_wait folgende Informationen finden:&lt;br /&gt;&lt;br /&gt;&lt;div class="codesnippet"&gt;&lt;pre&gt;SID       SEQ# EVENT            &lt;br /&gt;--- ---------- -----------------&lt;br /&gt;140        110 row cache lock   &lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;In Dion Chos (auch sonst sehr lesenswertem) &lt;a href="http://dioncho.wordpress.com/2009/10/15/finding-out-the-row-cache-lock-holder-through-v-view/"&gt;Blog&lt;/a&gt; findet man eine Erläuterung dazu, wie man den holder eines row cache locks mit Hilfe von v$rowcache_parent ermitteln kann, aber in meinem Fall genügte ein Blick in v$session, um die blocking_session zu bestimmen. In der Dokumentation habe ich dafür zwar die &lt;a href="http://download.oracle.com/docs/cd/B19306_01/server.102/b14237/waitevents003.htm#sthref3167"&gt;Kurzbeschreibung&lt;/a&gt; "The session is trying to get a data dictionary lock" gefunden, aber keine grundsätzlichere Erklärung (kann auch sein, dass mein Suche nicht besonders systematisch war). Offenbar handelt es sich um ein Lock im dictionary cache, aber wieso es für den v$session_longops-Zugriff relevant ist aber nicht für Zugriffe auf ähnliche Objekte, kann ich nicht sagen.&lt;br /&gt;&lt;br /&gt;Was ich immerhin herausgefunden habe, ist, dass die PK-Aktivierung ohne Verzögerung erfolgt, wenn der Index zur PK-Unterstützung als UNIQUE definiert ist, also:&lt;br /&gt;&lt;br /&gt;&lt;div class="codesnippet"&gt;&lt;pre&gt;create unique index big_t_idx on big_t(id);&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;Das ist durchaus einleuchtend - offenbar muss die Eindeutigkeit im Fall des non-unique Index erst explizit geprüft werden -, erklärt die Wirkung des "row cache lock" aber noch nicht. Wenn jemand mehr darüber weiß, würde ich mich über entsprechende Hinweise freuen.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Nachtrag 19.09.2011&lt;/b&gt;: Das &lt;i&gt;row cache lock&lt;/i&gt; tritt offenbar auch bei der nachträglichen Definition eines NOT NULL Constraints auf.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-2227726725085989851?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/2227726725085989851/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2011/09/row-cache-lock.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/2227726725085989851'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/2227726725085989851'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2011/09/row-cache-lock.html' title='Row Cache Lock'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-8230796936268155182</id><published>2011-09-12T11:51:00.000-07:00</published><updated>2011-09-13T23:29:26.489-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Trace'/><category scheme='http://www.blogger.com/atom/ns#' term='Hints'/><title type='text'>DBMS_STATS.DISPLAY - Outline Hints und Aliase</title><content type='html'>Da ich es sonst immer wieder anderswo nachschlagen muss, schreib ich endlich mal auf, wie man sich die Outline Hints und Subquery-Aliase einer Query mit Hilfe von DBMS_STATS.DISPLAY anzeigen lassen kann. Die Syntax dafür lautet einfach:&lt;br /&gt;&lt;br /&gt;&lt;div class="codesnippet"&gt;&lt;pre&gt;select *&lt;br /&gt;  from table(dbms_xplan.display('', '', 'ALIAS OUTLINE'));&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;In den Aliasen findet man dann mit etwas Glück auch die Labels wieder, die man einem Query Block mit Hilfe des QB_NAME hints geben kann, der (einmal mehr) bei &lt;a href="http://jonathanlewis.wordpress.com/2007/06/25/qb_name/"&gt;Jonathan Lewis&lt;/a&gt; ausführlicher beschrieben wurde.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-8230796936268155182?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/8230796936268155182/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2011/09/dbmsstatsdisplay-outline-hints-und.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/8230796936268155182'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/8230796936268155182'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2011/09/dbmsstatsdisplay-outline-hints-und.html' title='DBMS_STATS.DISPLAY - Outline Hints und Aliase'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-298194148421507758</id><published>2011-09-12T11:29:00.000-07:00</published><updated>2011-09-12T11:29:48.825-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Bug'/><category scheme='http://www.blogger.com/atom/ns#' term='Statistiken'/><title type='text'>System Statistic Bug in 11.2</title><content type='html'>Jonathan Lewis hat in seinem &lt;a href="http://jonathanlewis.wordpress.com/2011/09/12/system-stats/"&gt;Blog&lt;/a&gt; einige der einschlägigen Hinweise auf den Bug 9842771 gesammelt, der sich darin äußert, dass in AUX_STAT$ abwegig hohe Werte für SREADTIM and MREADTIM erscheinen.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-298194148421507758?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/298194148421507758/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2011/09/system-statistic-bug-in-112.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/298194148421507758'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/298194148421507758'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2011/09/system-statistic-bug-in-112.html' title='System Statistic Bug in 11.2'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-1317776131326464565</id><published>2011-09-09T06:44:00.000-07:00</published><updated>2011-09-13T23:36:54.557-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Index'/><title type='text'>Descending Indexes</title><content type='html'>Die &lt;a href="http://richardfoote.wordpress.com/2011/09/09/descending-indexes-solution-yellow-submarine/"&gt;nächste Quizfrage des Herrn Foote&lt;/a&gt;, diesmal zum Thema &lt;i&gt;Descending Indexes&lt;/i&gt;. Ohne die Details hier alle noch mal nacherzählen zu wollen, ein paar wichtige Punkte:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;ein DESC-Index ist vom Typ her FUNCTION-BASED NORMAL&lt;/li&gt;&lt;li&gt;beim Überlauf von Index-Blocks erfolgt ein 50/50 Spilt, was den Index weniger kompakt macht als einen ASC-Index, beim dem die Block-Splits 90/10 erfolgen (also eigentlich eher 99/1)&lt;/li&gt;&lt;li&gt;der RBO ignoriert neumodischen Kram wie FBIs&lt;/li&gt;&lt;/ul&gt;&lt;b&gt;Nachtrag 14.09.2011&lt;/b&gt;: in den Kommentaren zum Artikel haben sich auch noch die Herren Geist und Lewis zu Wort gemeldet und noch ein paar erinneringswürdige Fakten beigesteuert:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;descending indexes werden nicht für dynamic sampling in Betracht gezogen: "The reason for not using dynamic sampling on the descending index is  also interesting: The dynamic sampling code uses the original predicates  (between 42 and 84) and not the actual ones that are then applied to  the descending index (the SYS_OP… stuff), so it obviously doesn’t  consider the index as candidate for sampling." &lt;a href="http://richardfoote.wordpress.com/2011/09/09/descending-indexes-solution-yellow-submarine/#comment-32761"&gt;Randolf Geist&lt;/a&gt;&lt;/li&gt;&lt;li&gt;descending indexes sind pro row ein byte größer als entsprechend acs indexes: "the descending column is a one’s-bit complement of the original value, stored in ascending order, with a 0xff appended. This means the index will be one byte larger for each row for each  descending column – and that’s a pretty good reason for not making every  column in an index descending.  (Plus there are cases – possibly fixed  in 11.2 – where descending indexes won’t be used for plans which would  be considered for ascending indexes.)" &lt;a href="http://richardfoote.wordpress.com/2011/09/09/descending-indexes-solution-yellow-submarine/#comment-32792"&gt;Jonathan Lewis&lt;/a&gt;&lt;/li&gt;&lt;li&gt;ein dritter Kommentar zeigt, dass ein ALTER TABLE SHRINK SPACE für Tabellen mit einem DESC Index nicht funktioniert (und einen "ORA-10631: SHRINK clause should not be specified for this object" liefert)&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-1317776131326464565?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/1317776131326464565/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2011/09/descending-indexes.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/1317776131326464565'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/1317776131326464565'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2011/09/descending-indexes.html' title='Descending Indexes'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-3183161727377557407</id><published>2011-09-08T12:27:00.000-07:00</published><updated>2011-09-08T12:27:36.889-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Partitioning'/><category scheme='http://www.blogger.com/atom/ns#' term='Buffer Cache'/><title type='text'>Partitionierte Tabellen und direct path FTS</title><content type='html'>Über das in 11g eingeführte Feature der &lt;i&gt;direct path reads&lt;/i&gt; für &lt;i&gt;serial table scans&lt;/i&gt; hatte ich &lt;a href="http://oraganism.wordpress.com/2011/06/27/fun-with-_serial_direct_read/"&gt;schon&lt;/a&gt; &lt;a href="http://oracledoug.com/serendipity/index.php?/archives/1321-11g-and-direct-path-reads.html"&gt;mehrfach&lt;/a&gt; &lt;a href="http://afatkulin.blogspot.com/2009/01/11g-adaptive-direct-path-reads-what-is.html"&gt;gelesen&lt;/a&gt;, ohne mir viel dabei zu denken. Vor kurzem habe ich dann in &lt;a href="http://martinpreiss.blogspot.com/2011/08/tanel-poder-uber-full-scans-und-direct.html"&gt;Tanel Poders Hacking Session Video&lt;/a&gt; den Hinweis bekommen, dass die für die Entscheidung der run time engine, ob eine Tabelle für den direct path Zugriff in Betracht gezogen wird, relevante _small_table_threshold pro Segment definiert ist - also auch für die Partitionen einer partitionierten Tabelle. Trotzdem war ich heute zunächst überrascht, als ein einfaches SELECT COUNT(*) auf einer Heap-Tabelle mit 5.000.000 Sätzen (etwa 1 GB groß) in ca. 20 sec. ablief, während der Zugriff auf eine identisch gefüllte partitionierte Tabelle mehr als 40 sec. benötigte. Ein Vergleich der Statistiken in v$sesstat half meinem Gedächtnis dann auf die Sprünge:&lt;br /&gt;&lt;br /&gt;&lt;table border="0" cellpadding="0" cellspacing="0" class="MsoNormalTable" style="width: 500px;"&gt;&lt;tbody&gt;&lt;tr style="height: 14.25pt;"&gt;&lt;td style="height: 14.25pt; padding: 0cm 0cm 0cm 0cm; width: 191.0pt;" width="255"&gt;&lt;div class="MsoNormal"&gt;&lt;span style="color: #676767; font-family: &amp;quot;Arial&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;NAME&lt;/span&gt;&lt;span style="color: #676767; font-family: &amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/td&gt; &lt;td style="height: 14.25pt; padding: 0cm 0cm 0cm 0cm; width: 103.0pt;" width="137"&gt;&lt;div class="MsoNormal"&gt;&lt;span style="color: #676767; font-family: &amp;quot;Arial&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; TABLE_NO_PART&lt;/span&gt;&lt;span style="color: #676767; font-family: &amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/td&gt; &lt;td style="height: 14.25pt; padding: 0cm 0cm 0cm 0cm; width: 81.0pt;" width="108"&gt;&lt;div class="MsoNormal"&gt;&lt;span style="color: #676767; font-family: &amp;quot;Arial&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; TABLE_PART&lt;/span&gt;&lt;span style="color: #676767; font-family: &amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/td&gt; &lt;/tr&gt;&lt;tr style="height: 14.25pt;"&gt; &lt;td style="height: 14.25pt; padding: 0cm 0cm 0cm 0cm;"&gt;&lt;div class="MsoNormal"&gt;&lt;span style="color: #676767; font-family: &amp;quot;Arial&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;consistent gets&lt;/span&gt;&lt;span style="color: #676767; font-family: &amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/td&gt; &lt;td style="height: 14.25pt; padding: 0cm 0cm 0cm 0cm;"&gt;&lt;div align="right" class="MsoNormal" style="text-align: right;"&gt;&lt;span style="color: #676767; font-family: &amp;quot;Arial&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;72298&lt;/span&gt;&lt;span style="color: #676767; font-family: &amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/td&gt; &lt;td style="height: 14.25pt; padding: 0cm 0cm 0cm 0cm;"&gt;&lt;div align="right" class="MsoNormal" style="text-align: right;"&gt;&lt;span style="color: #676767; font-family: &amp;quot;Arial&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;74445&lt;/span&gt;&lt;span style="color: #676767; font-family: &amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/td&gt; &lt;/tr&gt;&lt;tr style="height: 14.25pt;"&gt; &lt;td style="height: 14.25pt; padding: 0cm 0cm 0cm 0cm;"&gt;&lt;div class="MsoNormal"&gt;&lt;span style="color: #676767; font-family: &amp;quot;Arial&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;consistent gets - examination&lt;/span&gt;&lt;span style="color: #676767; font-family: &amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/td&gt; &lt;td style="height: 14.25pt; padding: 0cm 0cm 0cm 0cm;"&gt;&lt;div align="right" class="MsoNormal" style="text-align: right;"&gt;&lt;span style="color: #676767; font-family: &amp;quot;Arial&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;0&lt;/span&gt;&lt;span style="color: #676767; font-family: &amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/td&gt; &lt;td style="height: 14.25pt; padding: 0cm 0cm 0cm 0cm;"&gt;&lt;div align="right" class="MsoNormal" style="text-align: right;"&gt;&lt;span style="color: #676767; font-family: &amp;quot;Arial&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;819&lt;/span&gt;&lt;span style="color: #676767; font-family: &amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/td&gt; &lt;/tr&gt;&lt;tr style="height: 14.25pt;"&gt; &lt;td style="height: 14.25pt; padding: 0cm 0cm 0cm 0cm;"&gt;&lt;div class="MsoNormal"&gt;&lt;span style="color: #676767; font-family: &amp;quot;Arial&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;consistent gets direct&lt;/span&gt;&lt;span style="color: #676767; font-family: &amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/td&gt; &lt;td style="height: 14.25pt; padding: 0cm 0cm 0cm 0cm;"&gt;&lt;div align="right" class="MsoNormal" style="text-align: right;"&gt;&lt;span style="color: #676767; font-family: &amp;quot;Arial&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;72286&lt;/span&gt;&lt;span style="color: #676767; font-family: &amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/td&gt; &lt;td style="height: 14.25pt; padding: 0cm 0cm 0cm 0cm;"&gt;&lt;div align="right" class="MsoNormal" style="text-align: right;"&gt;&lt;span style="color: #676767; font-family: &amp;quot;Arial&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;0&lt;/span&gt;&lt;span style="color: #676767; font-family: &amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/td&gt; &lt;/tr&gt;&lt;tr style="height: 14.25pt;"&gt; &lt;td style="height: 14.25pt; padding: 0cm 0cm 0cm 0cm;"&gt;&lt;div class="MsoNormal"&gt;&lt;span style="color: #676767; font-family: &amp;quot;Arial&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;consistent gets from cache&lt;/span&gt;&lt;span style="color: #676767; font-family: &amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/td&gt; &lt;td style="height: 14.25pt; padding: 0cm 0cm 0cm 0cm;"&gt;&lt;div align="right" class="MsoNormal" style="text-align: right;"&gt;&lt;span style="color: #676767; font-family: &amp;quot;Arial&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;12&lt;/span&gt;&lt;span style="color: #676767; font-family: &amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/td&gt; &lt;td style="height: 14.25pt; padding: 0cm 0cm 0cm 0cm;"&gt;&lt;div align="right" class="MsoNormal" style="text-align: right;"&gt;&lt;span style="color: #676767; font-family: &amp;quot;Arial&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;74445&lt;/span&gt;&lt;span style="color: #676767; font-family: &amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/td&gt; &lt;/tr&gt;&lt;tr style="height: 14.25pt;"&gt; &lt;td style="height: 14.25pt; padding: 0cm 0cm 0cm 0cm;"&gt;&lt;div class="MsoNormal"&gt;&lt;span lang="EN-US" style="color: #676767; font-family: &amp;quot;Arial&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;consistent gets from cache (fastpath)&lt;/span&gt;&lt;span lang="EN-US" style="color: #676767; font-family: &amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/td&gt; &lt;td style="height: 14.25pt; padding: 0cm 0cm 0cm 0cm;"&gt;&lt;div align="right" class="MsoNormal" style="text-align: right;"&gt;&lt;span style="color: #676767; font-family: &amp;quot;Arial&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;12&lt;/span&gt;&lt;span style="color: #676767; font-family: &amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/td&gt; &lt;td style="height: 14.25pt; padding: 0cm 0cm 0cm 0cm;"&gt;&lt;div align="right" class="MsoNormal" style="text-align: right;"&gt;&lt;span style="color: #676767; font-family: &amp;quot;Arial&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;71726&lt;/span&gt;&lt;span style="color: #676767; font-family: &amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/td&gt; &lt;/tr&gt;&lt;tr style="height: 14.25pt;"&gt; &lt;td style="height: 14.25pt; padding: 0cm 0cm 0cm 0cm;"&gt;&lt;div class="MsoNormal"&gt;&lt;span style="color: #676767; font-family: &amp;quot;Arial&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;DB time&lt;/span&gt;&lt;span style="color: #676767; font-family: &amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/td&gt; &lt;td style="height: 14.25pt; padding: 0cm 0cm 0cm 0cm;"&gt;&lt;div align="right" class="MsoNormal" style="text-align: right;"&gt;&lt;span style="color: #676767; font-family: &amp;quot;Arial&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;1699&lt;/span&gt;&lt;span style="color: #676767; font-family: &amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/td&gt; &lt;td style="height: 14.25pt; padding: 0cm 0cm 0cm 0cm;"&gt;&lt;div align="right" class="MsoNormal" style="text-align: right;"&gt;&lt;span style="color: #676767; font-family: &amp;quot;Arial&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;5046&lt;/span&gt;&lt;span style="color: #676767; font-family: &amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/td&gt; &lt;/tr&gt;&lt;tr style="height: 14.25pt;"&gt; &lt;td style="height: 14.25pt; padding: 0cm 0cm 0cm 0cm;"&gt;&lt;div class="MsoNormal"&gt;&lt;span style="color: #676767; font-family: &amp;quot;Arial&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;free buffer inspected&lt;/span&gt;&lt;span style="color: #676767; font-family: &amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/td&gt; &lt;td style="height: 14.25pt; padding: 0cm 0cm 0cm 0cm;"&gt;&lt;div align="right" class="MsoNormal" style="text-align: right;"&gt;&lt;span style="color: #676767; font-family: &amp;quot;Arial&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;0&lt;/span&gt;&lt;span style="color: #676767; font-family: &amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/td&gt; &lt;td style="height: 14.25pt; padding: 0cm 0cm 0cm 0cm;"&gt;&lt;div align="right" class="MsoNormal" style="text-align: right;"&gt;&lt;span style="color: #676767; font-family: &amp;quot;Arial&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;73410&lt;/span&gt;&lt;span style="color: #676767; font-family: &amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/td&gt; &lt;/tr&gt;&lt;tr style="height: 14.25pt;"&gt; &lt;td style="height: 14.25pt; padding: 0cm 0cm 0cm 0cm;"&gt;&lt;div class="MsoNormal"&gt;&lt;span style="color: #676767; font-family: &amp;quot;Arial&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;free buffer requested&lt;/span&gt;&lt;span style="color: #676767; font-family: &amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/td&gt; &lt;td style="height: 14.25pt; padding: 0cm 0cm 0cm 0cm;"&gt;&lt;div align="right" class="MsoNormal" style="text-align: right;"&gt;&lt;span style="color: #676767; font-family: &amp;quot;Arial&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;0&lt;/span&gt;&lt;span style="color: #676767; font-family: &amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/td&gt; &lt;td style="height: 14.25pt; padding: 0cm 0cm 0cm 0cm;"&gt;&lt;div align="right" class="MsoNormal" style="text-align: right;"&gt;&lt;span style="color: #676767; font-family: &amp;quot;Arial&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;72568&lt;/span&gt;&lt;span style="color: #676767; font-family: &amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/td&gt; &lt;/tr&gt;&lt;tr style="height: 14.25pt;"&gt; &lt;td style="height: 14.25pt; padding: 0cm 0cm 0cm 0cm;"&gt;&lt;div class="MsoNormal"&gt;&lt;span style="color: #676767; font-family: &amp;quot;Arial&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;physical reads&lt;/span&gt;&lt;span style="color: #676767; font-family: &amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/td&gt; &lt;td style="height: 14.25pt; padding: 0cm 0cm 0cm 0cm;"&gt;&lt;div align="right" class="MsoNormal" style="text-align: right;"&gt;&lt;span style="color: #676767; font-family: &amp;quot;Arial&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;72286&lt;/span&gt;&lt;span style="color: #676767; font-family: &amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/td&gt; &lt;td style="height: 14.25pt; padding: 0cm 0cm 0cm 0cm;"&gt;&lt;div align="right" class="MsoNormal" style="text-align: right;"&gt;&lt;span style="color: #676767; font-family: &amp;quot;Arial&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;72568&lt;/span&gt;&lt;span style="color: #676767; font-family: &amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/td&gt; &lt;/tr&gt;&lt;tr style="height: 14.25pt;"&gt; &lt;td style="height: 14.25pt; padding: 0cm 0cm 0cm 0cm;"&gt;&lt;div class="MsoNormal"&gt;&lt;span style="color: #676767; font-family: &amp;quot;Arial&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;physical reads cache&lt;/span&gt;&lt;span style="color: #676767; font-family: &amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/td&gt; &lt;td style="height: 14.25pt; padding: 0cm 0cm 0cm 0cm;"&gt;&lt;div align="right" class="MsoNormal" style="text-align: right;"&gt;&lt;span style="color: #676767; font-family: &amp;quot;Arial&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;0&lt;/span&gt;&lt;span style="color: #676767; font-family: &amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/td&gt; &lt;td style="height: 14.25pt; padding: 0cm 0cm 0cm 0cm;"&gt;&lt;div align="right" class="MsoNormal" style="text-align: right;"&gt;&lt;span style="color: #676767; font-family: &amp;quot;Arial&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;72568&lt;/span&gt;&lt;span style="color: #676767; font-family: &amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/td&gt; &lt;/tr&gt;&lt;tr style="height: 14.25pt;"&gt; &lt;td style="height: 14.25pt; padding: 0cm 0cm 0cm 0cm;"&gt;&lt;div class="MsoNormal"&gt;&lt;span style="color: #676767; font-family: &amp;quot;Arial&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;physical reads cache prefetch&lt;/span&gt;&lt;span style="color: #676767; font-family: &amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/td&gt; &lt;td style="height: 14.25pt; padding: 0cm 0cm 0cm 0cm;"&gt;&lt;div align="right" class="MsoNormal" style="text-align: right;"&gt;&lt;span style="color: #676767; font-family: &amp;quot;Arial&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;0&lt;/span&gt;&lt;span style="color: #676767; font-family: &amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/td&gt; &lt;td style="height: 14.25pt; padding: 0cm 0cm 0cm 0cm;"&gt;&lt;div align="right" class="MsoNormal" style="text-align: right;"&gt;&lt;span style="color: #676767; font-family: &amp;quot;Arial&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;70674&lt;/span&gt;&lt;span style="color: #676767; font-family: &amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/td&gt; &lt;/tr&gt;&lt;tr style="height: 14.25pt;"&gt; &lt;td style="height: 14.25pt; padding: 0cm 0cm 0cm 0cm;"&gt;&lt;div class="MsoNormal"&gt;&lt;span style="color: #676767; font-family: &amp;quot;Arial&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;physical reads direct&lt;/span&gt;&lt;span style="color: #676767; font-family: &amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/td&gt; &lt;td style="height: 14.25pt; padding: 0cm 0cm 0cm 0cm;"&gt;&lt;div align="right" class="MsoNormal" style="text-align: right;"&gt;&lt;span style="color: #676767; font-family: &amp;quot;Arial&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;72286&lt;/span&gt;&lt;span style="color: #676767; font-family: &amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/td&gt; &lt;td style="height: 14.25pt; padding: 0cm 0cm 0cm 0cm;"&gt;&lt;div align="right" class="MsoNormal" style="text-align: right;"&gt;&lt;span style="color: #676767; font-family: &amp;quot;Arial&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;0&lt;/span&gt;&lt;span style="color: #676767; font-family: &amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/td&gt; &lt;/tr&gt;&lt;tr style="height: 14.25pt;"&gt; &lt;td style="height: 14.25pt; padding: 0cm 0cm 0cm 0cm;"&gt;&lt;div class="MsoNormal"&gt;&lt;span style="color: #676767; font-family: &amp;quot;Arial&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;table scan blocks gotten&lt;/span&gt;&lt;span style="color: #676767; font-family: &amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/td&gt; &lt;td style="height: 14.25pt; padding: 0cm 0cm 0cm 0cm;"&gt;&lt;div align="right" class="MsoNormal" style="text-align: right;"&gt;&lt;span style="color: #676767; font-family: &amp;quot;Arial&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;72286&lt;/span&gt;&lt;span style="color: #676767; font-family: &amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/td&gt; &lt;td style="height: 14.25pt; padding: 0cm 0cm 0cm 0cm;"&gt;&lt;div align="right" class="MsoNormal" style="text-align: right;"&gt;&lt;span style="color: #676767; font-family: &amp;quot;Arial&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;72444&lt;/span&gt;&lt;span style="color: #676767; font-family: &amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/td&gt; &lt;/tr&gt;&lt;tr style="height: 14.25pt;"&gt; &lt;td style="height: 14.25pt; padding: 0cm 0cm 0cm 0cm;"&gt;&lt;div class="MsoNormal"&gt;&lt;span style="color: #676767; font-family: &amp;quot;Arial&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;table scan rows gotten&lt;/span&gt;&lt;span style="color: #676767; font-family: &amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/td&gt; &lt;td style="height: 14.25pt; padding: 0cm 0cm 0cm 0cm;"&gt;&lt;div align="right" class="MsoNormal" style="text-align: right;"&gt;&lt;span style="color: #676767; font-family: &amp;quot;Arial&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;5637076&lt;/span&gt;&lt;span style="color: #676767; font-family: &amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/td&gt; &lt;td style="height: 14.25pt; padding: 0cm 0cm 0cm 0cm;"&gt;&lt;div align="right" class="MsoNormal" style="text-align: right;"&gt;&lt;span style="color: #676767; font-family: &amp;quot;Arial&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;5637107&lt;/span&gt;&lt;span style="color: #676767; font-family: &amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/td&gt; &lt;/tr&gt;&lt;tr style="height: 14.25pt;"&gt; &lt;td style="height: 14.25pt; padding: 0cm 0cm 0cm 0cm;"&gt;&lt;div class="MsoNormal"&gt;&lt;span style="color: #676767; font-family: &amp;quot;Arial&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;table scans (direct read)&lt;/span&gt;&lt;span style="color: #676767; font-family: &amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/td&gt; &lt;td style="height: 14.25pt; padding: 0cm 0cm 0cm 0cm;"&gt;&lt;div align="right" class="MsoNormal" style="text-align: right;"&gt;&lt;span style="color: #676767; font-family: &amp;quot;Arial&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;1&lt;/span&gt;&lt;span style="color: #676767; font-family: &amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/td&gt; &lt;td style="height: 14.25pt; padding: 0cm 0cm 0cm 0cm;"&gt;&lt;div align="right" class="MsoNormal" style="text-align: right;"&gt;&lt;span style="color: #676767; font-family: &amp;quot;Arial&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;0&lt;/span&gt;&lt;span style="color: #676767; font-family: &amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/td&gt; &lt;/tr&gt;&lt;tr style="height: 14.25pt;"&gt; &lt;td style="height: 14.25pt; padding: 0cm 0cm 0cm 0cm;"&gt;&lt;div class="MsoNormal"&gt;&lt;span style="color: #676767; font-family: &amp;quot;Arial&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;table scans (long tables)&lt;/span&gt;&lt;span style="color: #676767; font-family: &amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/td&gt; &lt;td style="height: 14.25pt; padding: 0cm 0cm 0cm 0cm;"&gt;&lt;div align="right" class="MsoNormal" style="text-align: right;"&gt;&lt;span style="color: #676767; font-family: &amp;quot;Arial&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;1&lt;/span&gt;&lt;span style="color: #676767; font-family: &amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/td&gt; &lt;td style="height: 14.25pt; padding: 0cm 0cm 0cm 0cm;"&gt;&lt;div align="right" class="MsoNormal" style="text-align: right;"&gt;&lt;span style="color: #676767; font-family: &amp;quot;Arial&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;0&lt;/span&gt;&lt;span style="color: #676767; font-family: &amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/td&gt; &lt;/tr&gt;&lt;tr style="height: 14.25pt;"&gt; &lt;td style="height: 14.25pt; padding: 0cm 0cm 0cm 0cm;"&gt;&lt;div class="MsoNormal"&gt;&lt;span style="color: #676767; font-family: &amp;quot;Arial&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;table scans (short tables)&lt;/span&gt;&lt;span style="color: #676767; font-family: &amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/td&gt; &lt;td style="height: 14.25pt; padding: 0cm 0cm 0cm 0cm;"&gt;&lt;div align="right" class="MsoNormal" style="text-align: right;"&gt;&lt;span style="color: #676767; font-family: &amp;quot;Arial&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;0&lt;/span&gt;&lt;span style="color: #676767; font-family: &amp;quot;Verdana&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;/td&gt; &lt;td style="height: 14.25pt; padding: 0cm 0cm 0cm 0cm;"&gt;&lt;div align="right" class="MsoNormal" style="text-align: right;"&gt;&lt;span style="color: #676767; font-family: &amp;quot;Arial&amp;quot;,&amp;quot;sans-serif&amp;quot;; font-size: 8pt;"&gt;86&lt;/span&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;Die 86 &lt;i&gt;table scans (short tables)&lt;/i&gt; gehören zu den Partitionen, während für die nicht partitionierte Tabelle ein &lt;i&gt;table scan (long tables)&lt;/i&gt; erscheint - und dieser ruft dann consistent gets direct hervor, während die kleineren Partitionen über den Buffer Cache gelesen werden, was zumindest in diesem Fall deutlich langsamer ist. Die Entscheidung für den direct path Zugriff kann übrigens mit Hilfe des Parameters _serial_direct_read beeinflusst werden, der wie alle hidden parameter natürlich nur nach Rücksprache mit dem zuständigen Arzt oder Apotheker verwendet werden sollte.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-3183161727377557407?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/3183161727377557407/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2011/09/partitionierte-tabellen-und-direct-path.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/3183161727377557407'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/3183161727377557407'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2011/09/partitionierte-tabellen-und-direct-path.html' title='Partitionierte Tabellen und direct path FTS'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-6647109545130496856</id><published>2011-09-05T12:50:00.000-07:00</published><updated>2011-09-07T06:52:14.150-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Buffer Cache'/><title type='text'>Einzelsatzzugriff</title><content type='html'>Und schon wieder eine Quizfrage des Herrn &lt;a href="http://richardfoote.wordpress.com/2011/09/05/best-method-to-select-one-row-from-small-table-quiz-each-small-candle/"&gt;Foote&lt;/a&gt;: &lt;br /&gt;&lt;blockquote&gt;Assume you have a tiny little table with just 42 rows (naturally) that all fit in &lt;b&gt;one table block&lt;/b&gt;.&amp;nbsp;Order the following options in order of “efficiency” (most efficient option first) when accessing just one of these rows:&lt;br /&gt;1) Full Table Scan of Heap Table&lt;br /&gt;2) PK access of an Index Organised Table&lt;br /&gt;3) Index access of Heap Table via a Unique Index&lt;br /&gt;4) Index access of Heap Table via a Non-Unique Index&lt;/blockquote&gt;&lt;br /&gt;In den Kommentaren wurden gleich ein paar berechtigte Nachfragen gestellt, aber ich tu mal so, als sei die Frage völlig harmlos:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;1. FTS&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="codesnippet"&gt;&lt;pre&gt;create table t42 tablespace test_ts&lt;br /&gt;as&lt;br /&gt;select rownum id&lt;br /&gt;     , 'Ziggy' col2&lt;br /&gt;  from dual&lt;br /&gt;connect by level &amp;lt;= 42;&lt;br /&gt;&lt;br /&gt;exec dbms_stats.gather_table_stats(user, 'T42')&lt;br /&gt;&lt;br /&gt;select *&lt;br /&gt;  from t42&lt;br /&gt; where id = 1;&lt;br /&gt;&lt;br /&gt;   ID COL2&lt;br /&gt;----- -----&lt;br /&gt;    1 Ziggy&lt;br /&gt;&lt;br /&gt;--------------------------------------------------------------------------&lt;br /&gt;| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |&lt;br /&gt;--------------------------------------------------------------------------&lt;br /&gt;|   0 | SELECT STATEMENT  |      |     1 |     9 |     2   (0)| 00:00:01 |&lt;br /&gt;|*  1 |  TABLE ACCESS FULL| T42  |     1 |     9 |     2   (0)| 00:00:01 |&lt;br /&gt;--------------------------------------------------------------------------&lt;br /&gt;&lt;br /&gt;Predicate Information (identified by operation id):&lt;br /&gt;---------------------------------------------------&lt;br /&gt;&lt;br /&gt;   1 - filter("ID"=1)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Statistiken&lt;br /&gt;----------------------------------------------------------&lt;br /&gt;          0  recursive calls&lt;br /&gt;          0  db block gets&lt;br /&gt;          4  consistent gets&lt;br /&gt;          0  physical reads&lt;br /&gt;          0  redo size&lt;br /&gt;        599  bytes sent via SQL*Net to client&lt;br /&gt;        520  bytes received via SQL*Net from client&lt;br /&gt;          2  SQL*Net roundtrips to/from client&lt;br /&gt;          0  sorts (memory)&lt;br /&gt;          0  sorts (disk)&lt;br /&gt;          1  rows processed&lt;/pre&gt;&lt;pre&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;b&gt;2. non-unique Index&lt;/b&gt; &lt;br /&gt;&lt;br /&gt;&lt;div class="codesnippet"&gt;&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;create index t42_idx on t42(id);&lt;br /&gt;&lt;br /&gt;--&amp;gt; Query&lt;br /&gt;&lt;br /&gt;---------------------------------------------------------------------------------------&lt;br /&gt;| Id  | Operation                   | Name    | Rows  | Bytes | Cost (%CPU)| Time     |&lt;br /&gt;---------------------------------------------------------------------------------------&lt;br /&gt;|   0 | SELECT STATEMENT            |         |     1 |     9 |     2   (0)| 00:00:01 |&lt;br /&gt;|   1 |  TABLE ACCESS BY INDEX ROWID| T42     |     1 |     9 |     2   (0)| 00:00:01 |&lt;br /&gt;|*  2 |   INDEX RANGE SCAN          | T42_IDX |     1 |       |     1   (0)| 00:00:01 |&lt;br /&gt;---------------------------------------------------------------------------------------&lt;br /&gt;&lt;br /&gt;Predicate Information (identified by operation id):&lt;br /&gt;---------------------------------------------------&lt;br /&gt;&lt;br /&gt;   2 - access("ID"=1)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Statistiken&lt;br /&gt;----------------------------------------------------------&lt;br /&gt;          1  recursive calls&lt;br /&gt;          0  db block gets&lt;br /&gt;          3  consistent gets&lt;br /&gt;          0  physical reads&lt;br /&gt;          0  redo size&lt;br /&gt;        603  bytes sent via SQL*Net to client&lt;br /&gt;        520  bytes received via SQL*Net from client&lt;br /&gt;          2  SQL*Net roundtrips to/from client&lt;br /&gt;          0  sorts (memory)&lt;br /&gt;          0  sorts (disk)&lt;br /&gt;          1  rows processed&lt;/pre&gt;&lt;pre&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;b&gt;3. Unique Index&lt;/b&gt;  &lt;br /&gt;&lt;br /&gt;&lt;div class="codesnippet"&gt;&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;create unique index t42_uidx on t42(id);&lt;br /&gt;&lt;br /&gt;--&amp;gt; Query&lt;br /&gt;&lt;br /&gt;----------------------------------------------------------------------------------------&lt;br /&gt;| Id  | Operation                   | Name     | Rows  | Bytes | Cost (%CPU)| Time     |&lt;br /&gt;----------------------------------------------------------------------------------------&lt;br /&gt;|   0 | SELECT STATEMENT            |          |     1 |     9 |     1   (0)| 00:00:01 |&lt;br /&gt;|   1 |  TABLE ACCESS BY INDEX ROWID| T42      |     1 |     9 |     1   (0)| 00:00:01 |&lt;br /&gt;|*  2 |   INDEX UNIQUE SCAN         | T42_UIDX |     1 |       |     0   (0)| 00:00:01 |&lt;br /&gt;----------------------------------------------------------------------------------------&lt;br /&gt;&lt;br /&gt;Predicate Information (identified by operation id):&lt;br /&gt;---------------------------------------------------&lt;br /&gt;&lt;br /&gt;   2 - access("ID"=1)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Statistiken&lt;br /&gt;----------------------------------------------------------&lt;br /&gt;          1  recursive calls&lt;br /&gt;          0  db block gets&lt;br /&gt;          2  consistent gets&lt;br /&gt;          0  physical reads&lt;br /&gt;          0  redo size&lt;br /&gt;        467  bytes sent via SQL*Net to client&lt;br /&gt;        509  bytes received via SQL*Net from client&lt;br /&gt;          1  SQL*Net roundtrips to/from client&lt;br /&gt;          0  sorts (memory)&lt;br /&gt;          0  sorts (disk)&lt;br /&gt;          1  rows processed&lt;/pre&gt;&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;&lt;b&gt;4. IOT-Zugriff&lt;/b&gt;  &lt;br /&gt;&lt;br /&gt;&lt;div class="codesnippet"&gt;&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;&lt;pre&gt;create table t42 (id, col2, constraint t42pk primary key(id)) organization index tablespace test_ts&lt;br /&gt;as&lt;br /&gt;select rownum id&lt;br /&gt;     , 'Ziggy' col2&lt;br /&gt;  from dual&lt;br /&gt;connect by level &amp;lt;= 42&lt;br /&gt;&lt;br /&gt;exec dbms_stats.gather_table_stats(user, 'T42')&lt;br /&gt;&lt;br /&gt;--&amp;gt; Query&lt;br /&gt;&lt;br /&gt;---------------------------------------------------------------------------&lt;br /&gt;| Id  | Operation         | Name  | Rows  | Bytes | Cost (%CPU)| Time     |&lt;br /&gt;---------------------------------------------------------------------------&lt;br /&gt;|   0 | SELECT STATEMENT  |       |     1 |     9 |     0   (0)| 00:00:01 |&lt;br /&gt;|*  1 |  INDEX UNIQUE SCAN| T42PK |     1 |     9 |     0   (0)| 00:00:01 |&lt;br /&gt;---------------------------------------------------------------------------&lt;br /&gt;&lt;br /&gt;Predicate Information (identified by operation id):&lt;br /&gt;---------------------------------------------------&lt;br /&gt;&lt;br /&gt;   1 - access("ID"=1)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Statistiken&lt;br /&gt;----------------------------------------------------------&lt;br /&gt;          1  recursive calls&lt;br /&gt;          0  db block gets&lt;br /&gt;          1  consistent gets&lt;br /&gt;          0  physical reads&lt;br /&gt;          0  redo size&lt;br /&gt;        599  bytes sent via SQL*Net to client&lt;br /&gt;        520  bytes received via SQL*Net from client&lt;br /&gt;          2  SQL*Net roundtrips to/from client&lt;br /&gt;          0  sorts (memory)&lt;br /&gt;          0  sorts (disk)&lt;br /&gt;          1  rows processed&lt;/pre&gt;&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;&lt;/div&gt;&lt;b&gt;&lt;br /&gt;5. Single Table Hash Cluster&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Nicht in der Fragestellung enthalten, aber halbwegs zum Thema passend...&lt;br /&gt;&lt;br /&gt;&lt;div class="codesnippet"&gt;&lt;pre&gt;create cluster t_cluster&lt;br /&gt;(id number(2,0))&lt;br /&gt;tablespace test_ts&lt;br /&gt;hash is id hashkeys 64;&lt;br /&gt;&lt;br /&gt;create table t42&lt;br /&gt;( id number(2,0)&lt;br /&gt;, col2 varchar2(10) )&lt;br /&gt;cluster t_cluster (id);&lt;br /&gt;&lt;br /&gt;insert into t42&lt;br /&gt;select rownum id&lt;br /&gt;     , 'Ziggy' col2&lt;br /&gt;  from dual&lt;br /&gt;connect by level &amp;lt;= 42;&lt;br /&gt;&lt;br /&gt;--&amp;gt; Query&lt;br /&gt;&lt;br /&gt;---------------------------------------------------------------&lt;br /&gt;| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)|&lt;br /&gt;---------------------------------------------------------------&lt;br /&gt;|   0 | SELECT STATEMENT  |      |     1 |     9 |     0   (0)|&lt;br /&gt;|*  1 |  TABLE ACCESS HASH| T42  |     1 |     9 |            |&lt;br /&gt;---------------------------------------------------------------&lt;br /&gt;&lt;br /&gt;Predicate Information (identified by operation id):&lt;br /&gt;---------------------------------------------------&lt;br /&gt;&lt;br /&gt;   1 - access("ID"=1)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Statistiken&lt;br /&gt;----------------------------------------------------------&lt;br /&gt;          0  recursive calls&lt;br /&gt;          0  db block gets&lt;br /&gt;          1  consistent gets&lt;br /&gt;          0  physical reads&lt;br /&gt;          0  redo size&lt;br /&gt;        599  bytes sent via SQL*Net to client&lt;br /&gt;        520  bytes received via SQL*Net from client&lt;br /&gt;          2  SQL*Net roundtrips to/from client&lt;br /&gt;          0  sorts (memory)&lt;br /&gt;          0  sorts (disk)&lt;br /&gt;          1  rows processed&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;Also keine Überraschungen bei den Platzierungen:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;IOT (und HashCluster) mit 1 consistent get für den Zugriff auf einen einzelnen Datensatz (+ 1 Latch)&lt;/li&gt;&lt;li&gt;unique Index Zugriff mit 2 consistent gets (+ 2 Latches; nur 2 - also 1 pro LIO -, da es sich um &lt;i&gt;consistent get - examinations&lt;/i&gt;)&lt;/li&gt;&lt;li&gt;non-unique Index Zugriff mit 3 consistent gets (+ 6 Latches)&lt;/li&gt;&lt;li&gt;FTS mit 4 consistent get (+ 8 Latches)&lt;/li&gt;&lt;/ol&gt;Warum das so ist, hat der Herr Foote übrigens gelegentlich schon mal in seinem Blog&lt;a href="http://richardfoote.wordpress.com/2009/05/13/indexes-and-small-tables-part-v-its-no-game/"&gt;&lt;/a&gt; erläutert:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;beim &lt;a href="http://richardfoote.wordpress.com/2009/04/29/indexes-on-small-tables-part-iii-another-brick-in-the-wall-part-iii/"&gt;non-unique Index&lt;/a&gt; sind zwei Fetches erforderlich: einer zum Lesen des Ergebnisses und einer, um sicher zu gehen, dass nicht noch ein Satz für den gegebenen Wert folgt &lt;/li&gt;&lt;li&gt;beim &lt;a href="http://richardfoote.wordpress.com/2009/05/13/indexes-and-small-tables-part-v-its-no-game/"&gt;unique Index&lt;/a&gt; kann sich Oracle die zweite Fetch-Operation sparen, da nicht mehr als ein Satz zum Schlüssel vorliegen kann&amp;nbsp;&lt;/li&gt;&lt;li&gt;auch zum &lt;a href="http://richardfoote.wordpress.com/2009/04/16/indexes-on-small-tables-part-i-one-of-the-few/"&gt;FTS&lt;/a&gt; findet sich dort ein Artikel - und wahrscheinlich wären die beiden übrigen Artikel der fraglichen Serie &lt;i&gt;Indexes And Small Tables&lt;/i&gt; auch noch verlinkungswürdig - falls das ein Wort sein sollte...&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;b&gt;Nachtrag 07.09.2011&lt;/b&gt;: Inzwischen hat Richard Foote die &lt;a href="http://richardfoote.wordpress.com/2011/09/07/best-method-to-select-one-row-from-small-table-solution-revolution-1/"&gt;Antwort auf seine Fragen&lt;/a&gt; gegeben und dabei auch die angesprochenen älteren Artikel verlinkt. Interessant sind auch noch die dort angegebenen Latch-Zahlen, die ich oben im Ergebnis ergänzt habe.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-6647109545130496856?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/6647109545130496856/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2011/09/einzelsatzzugriff.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/6647109545130496856'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/6647109545130496856'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2011/09/einzelsatzzugriff.html' title='Einzelsatzzugriff'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-5306837514617194823</id><published>2011-09-04T06:12:00.000-07:00</published><updated>2011-09-04T06:12:15.197-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Undo'/><title type='text'>used_urec</title><content type='html'>Jonathan Lewis erläutert in seinem Blog, wie die Spalte used_urec in V$TRANSACTION gedeutet werden kann:&lt;br /&gt;&lt;blockquote&gt;when you insert a row, you typically generate one undo record (&lt;strong&gt;&lt;em&gt;used_urec&lt;/em&gt;&lt;/strong&gt;)  for the row, but when you insert many rows using an array insert Oracle  has an optimisation mechanism on undo record creation that allows it to  create one &lt;em&gt;&lt;strong&gt;used_urec&lt;/strong&gt;&lt;/em&gt; to cover all the changes you have made &lt;strong&gt;simultaneously &lt;/strong&gt;to an individual &lt;strong&gt;block &lt;/strong&gt;- so &lt;em&gt;&lt;strong&gt;used_urec&lt;/strong&gt;&lt;/em&gt; could be much smaller than the number of rows processed. &lt;br /&gt;However, if you have indexes in place and are doing normal index  maintenance on import, then each table row would require each index to  be updated, so you would go back to one &lt;em&gt;&lt;strong&gt;used_urec&lt;/strong&gt;&lt;/em&gt; per table row plus one &lt;em&gt;&lt;strong&gt;used_urec&lt;/strong&gt;&lt;/em&gt; per index maintained per table row.&lt;br /&gt;So, when you look at the “big picture” there’s no obvious correlation  between rows inserted and undo generated — until you look at the fine  detail of exactly what you’re doing, and whether any optimisations  apply. (The details of the optimisation strategies available vary with  the chosen insert mechanisms and with version of Oracle)&lt;/blockquote&gt;Außerdem verweist er auf einen älteren &lt;a href="http://jonathanlewis.wordpress.com/2010/09/22/session-undo/"&gt;Artikel&lt;/a&gt; zum Thema &lt;i&gt;Session Undo&lt;/i&gt; und darin dann wiederum auf ein &lt;a href="http://www.ixora.com.au/scripts/sql/9.0/rolling_back.sql"&gt;Script von Steve Adams&lt;/a&gt;, mit dessen Hilfe sich die Restlaufzeit eines Rollback-Vorgangs bestimmen lässt (sofern man Zugriff auf die erforderlichen v$- und x$-Objekte besitzt).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-5306837514617194823?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/5306837514617194823/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2011/09/usedurec.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/5306837514617194823'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/5306837514617194823'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2011/09/usedurec.html' title='used_urec'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-9142833057733515375</id><published>2011-09-04T05:58:00.000-07:00</published><updated>2011-09-04T05:58:09.829-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Trace'/><category scheme='http://www.blogger.com/atom/ns#' term='Tools'/><title type='text'>Automatic Diagnostic Repository Command Interpreter (ADRCI)</title><content type='html'>Trotz des anspruchsvoll klingenden Titels nur ein Link auf &lt;a href="http://uhesse.wordpress.com/2011/06/01/adrci-a-survival-guide-for-the-dba/"&gt;Uwe Hesses einführenden Artikel&lt;/a&gt; zu diesem 11er Tool zur Administration von Trace-Informationen.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-9142833057733515375?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/9142833057733515375/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2011/09/automatic-diagnostic-repository-command.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/9142833057733515375'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/9142833057733515375'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2011/09/automatic-diagnostic-repository-command.html' title='Automatic Diagnostic Repository Command Interpreter (ADRCI)'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-7923407065219364278</id><published>2011-09-02T10:42:00.000-07:00</published><updated>2011-09-02T23:35:07.234-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Histograms'/><title type='text'>Frequency-Histogramme und die 254 Bucket-Grenze</title><content type='html'>Und gleich die nächste interessante &lt;a href="http://richardfoote.wordpress.com/2011/08/31/method_opt-size-auto-quiz-automatic-for-the-people/"&gt;Quizfrage&lt;/a&gt; im Blog des Herrn Foote. Bei der &lt;a href="http://martinpreiss.blogspot.com/2011/08/minmax-abfragen-und-index-verwendung.html"&gt;letzten Frage&lt;/a&gt; war mir die Antwort schon vor der Auflösung klar, aber diesmal hatte ich absolut keine Erklärung für das beschriebene Verhalten: für eine Spalte existierte ein Frequency-Histogramm so lange darin 254 unterschiedliche - und gleichverteilte - Werte vorlagen. Das Hinzufügen eines einzelnen Satzes mit einem neuen und weit außerhalb des bisherigen Ranges liegenden Wert (also Nr. 255) führte dann dazu, dass bei erneuter Statsitikerzeugung mit der METHOD_OPT SIZE AUTO Option kein Histogram mehr erzeugt wurde - obwohl ein solches mit der neuen Datenverteilung sehr viel sinnvoller gewesen wäre als für den Fall vor der Ergänzung (für den ohnehin eine Gleichverteilung galt, die der cbo in Abwesenheit von Histogrammen von vornherein angenommen hätte). Die &lt;a href="http://richardfoote.wordpress.com/2011/09/01/method_opt-size-auto-quiz-solution-the-trickster/"&gt;Erklärung des Verhaltens&lt;/a&gt; lautet:&lt;br /&gt;&lt;blockquote&gt;When using METHOD_OPT SIZE AUTO, every column with 254 or less distinct values that has been referenced within a predicate, will have a Frequency-based histogram. Each and every one of them, regardless of whether the data is actually skewed or not.&lt;br /&gt;[...]&lt;br /&gt;If a column has more than 254 distinct values, whether it then has a Height-Based histogram depends on how the data is skewed.&lt;/blockquote&gt;Für die Spalte mit dem neuen und von den bisherigen Werten massiv abweichenden Wert gilt:&lt;br /&gt;&lt;blockquote&gt;Having inserted the outlier value, it now has 255 distinct values and so no longer qualifies for an automatic frequency based histogram. However, if all its values are evenly distributed, then it won’t qualify for a height based histogram either and Column 3 only has just the one outlier value, all other values are evenly distributed values. Unfortunately, Oracle doesn’t pick up on rare outlier values (even if you collect 100% statistics and it’s one of the low/high points of the column) and so will not generate a height-based histogram.&lt;/blockquote&gt;Der Artikel führt auch noch vor, dass das Fehlen des Histogramms dann recht extreme Fehleinschätzungen des cbo nach sich zieht, da dieser nun wieder eine Gleichverteilung annimmt. Vorgestern Abend bin ich an dieser Quizfrage fast 1,5 h hängengeblieben - es ist einfach großartig, was man bei den kompetentesten Oracle-Bloggern alles lernen kann.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Nachtrag 03.09.2011&lt;/b&gt;: Randolf Geist hat in einem &lt;a href="http://richardfoote.wordpress.com/2011/09/01/method_opt-size-auto-quiz-solution-the-trickster/#comment-31285"&gt;Kommentar&lt;/a&gt; zu Richard Footes Artikel noch einige wichtige Details zur Kostenberechnung des CBO mit Frequency Histograms ausgeführt.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-7923407065219364278?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/7923407065219364278/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2011/09/frequency-histogramme-und-die-254.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/7923407065219364278'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/7923407065219364278'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2011/09/frequency-histogramme-und-die-254.html' title='Frequency-Histogramme und die 254 Bucket-Grenze'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-5313162616891697642</id><published>2011-08-31T07:57:00.000-07:00</published><updated>2011-08-31T07:57:15.473-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Index'/><title type='text'>MIN/MAX Abfragen und Index-Verwendung</title><content type='html'>Dieser Tage hat Richard Foote in seinem Blog eine Quizfrage zur Abfrage der minimalen und maximalen Werte einer indizierten Spalte gestellt und inzwischen dazu auf eine &lt;a href="http://richardfoote.wordpress.com/2011/08/31/min-max-quiz-answer-one-shot/"&gt;ausführliche Antwort&lt;/a&gt; geliefert. Kurz zusammengefasst geht es darum, dass eine Query:&lt;br /&gt;&lt;br /&gt;&lt;div class="codesnippet"&gt;&lt;pre&gt;select min(col_ind)&lt;br /&gt;     , max(col_ind)&lt;br /&gt;  from ...&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;den bestehenden Index nur zum INDEX FAST FULL SCAN verwenden kann, während der wünschenswerte INDEX FULL SCAN (MIN/MAX) nur nutzbar ist, wenn man daraus zwei Zugriffe macht, was auf verschiedenen Wegen möglich ist.&lt;br /&gt;&lt;br /&gt;Herr Foote und die Kommentatoren sprechen eher über B*Tree-Indizes, aber das Verhalten von Bitmap-Indizes ist identisch.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-5313162616891697642?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/5313162616891697642/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2011/08/minmax-abfragen-und-index-verwendung.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/5313162616891697642'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/5313162616891697642'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2011/08/minmax-abfragen-und-index-verwendung.html' title='MIN/MAX Abfragen und Index-Verwendung'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-553421808370959671</id><published>2011-08-31T00:40:00.000-07:00</published><updated>2011-08-31T00:40:47.296-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='External Tables'/><title type='text'>External Tables und ORA-29913</title><content type='html'>Bei der Analyse von Zugriffsproblemen auf External Tables bzw. die darunter liegenden Directories und enthaltene Dateien habe ich bei &lt;a href="http://jonathanlewis.wordpress.com/2011/02/15/ora-29913/"&gt;Jonathan Lewis&lt;/a&gt; einen sehr nützlichen Artikel zu den Oracle-Fehlern ORA-29913 und ORA-29400 gefunden.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-553421808370959671?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/553421808370959671/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2011/08/external-tables-und-ora-29913.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/553421808370959671'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/553421808370959671'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2011/08/external-tables-und-ora-29913.html' title='External Tables und ORA-29913'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-6245731422671048389</id><published>2011-08-27T13:44:00.000-07:00</published><updated>2011-10-17T06:06:42.813-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Blocks'/><category scheme='http://www.blogger.com/atom/ns#' term='Buffer Cache'/><title type='text'>Tanel Poder über Full Scans und Direct Path Reads</title><content type='html'>Wieder ein Video in Spielfilmlänge von &lt;a href="http://blog.tanelpoder.com/2011/08/11/full-scans-direct-path-reads-and-ora-8103-error-hacking-session-video-here-plus-itunes-podcast-address-2"&gt;Tanel Poder&lt;/a&gt;. Details dazu vielleicht, wenn ich es komplett gesehen habe ...&lt;br /&gt;&lt;br /&gt;Nach Betrachtung der ersten 45 min des Videos ein paar erinnerungswürdige Punkte:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Der &lt;i&gt;Segment Header Block&lt;/i&gt; enthält Pointer auf die Extents des Segments.&lt;/li&gt;&lt;li&gt;In Oracle 7 war die Anzahl der Extents eines Segments begrenzt, da abhängig von der Blockgröße nur eine bestimmte Anzahl von Pointern untergebracht werden konnte. Aus diesem Grund musste man Segmente von Zeit zu Zeit reorganisieren, um die Anzahl der Extents zu reduzieren.&lt;/li&gt;&lt;li&gt;Seit Oracle 8 gibt es zusätzliche &lt;i&gt;extent map blocks&lt;/i&gt;, auf die im Segment Header verwiesen wird.&lt;/li&gt;&lt;li&gt;In &lt;i&gt;dictionary managed tablespaces&lt;/i&gt; wurde die Verwendung von Extents noch explizit in Tabellen des data dictionary gespeichert (SYS.UET$: used extents; SYS.FET$: free extents). In aktuellen Releases (ohne &lt;i&gt;dictionary managed tablespaces&lt;/i&gt;) sind diese Tabellen leer.&lt;/li&gt;&lt;li&gt;Ein Block Dump des &lt;i&gt;Segment Header Blocks&lt;/i&gt; liefert weitere Details:&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Der Dump enthält Informationen zur HWM, vor allem die Angabe &lt;i&gt;#blocks below&lt;/i&gt;.&lt;/li&gt;&lt;li&gt;diese Angabe ist die Grundlage für die Entscheidung, ob die Tabelle (bzw. eigentlich das Segment) als &lt;i&gt;long&lt;/i&gt; betrachtet wird, worauf wiederum die Entscheidung beruht, ob ein FTS über den Buffer Cache oder über direct path durchgeführt wird.&lt;/li&gt;&lt;li&gt;Im Header Block folgt dann die &lt;i&gt;Extent Map&lt;/i&gt; mit den Hex-Angaben der Blockadressen (die man mit Tanel Poders Script "DBA" auflösen kann).&lt;/li&gt;&lt;li&gt;Dann folgt die &lt;i&gt;Auxillary Map&lt;/i&gt; mit Verweisen auf die zusätzlichen Map Blocks.&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Für jeden Segment-Zugriff wird zunächst ein sequential read durchgeführt, um den &lt;i&gt;Segment Header Block&lt;/i&gt; zu lesen (sofern dieser nicht bereits im Buffer Cache vorliegt; deshalb wurde in der Demo zunächst ein Flush des Buffer Caches durchgeführt).&lt;/li&gt;&lt;li&gt;Die Idee der direct path FTS ist, den sinnvoll gefüllten Buffer Cache nicht durch massive Lese-Operationen für große FTS durcheinander zu bringen.&lt;/li&gt;&lt;li&gt;im 10046er Trace folgt auf den Header-Zugriff ein Event &lt;a href="http://blog.tanelpoder.com/2010/11/23/asynch-descriptor-resize-wait-event-in-oracle/"&gt;&lt;i&gt;async descriptor resize&lt;/i&gt;&lt;/a&gt; über das Tanel Poder schon mal geschreiben hat: "This KCBL module [= direct path loader] tries to dynamically scale up the number of asynch IO  descriptors (AIO descriptors are the OS kernel structures, which keep  track of asynch IO requests) to match the number of direct path &lt;b&gt;IO slots&lt;/b&gt;  a process uses. In other words, if the PGA workarea and/or spilled-over  hash area in temp tablespace gets larger, Oracle also scales up the  number of direct IO slots. Direct IO slots are PGA memory structures  helping to do direct IO between files and PGA."&lt;/li&gt;&lt;li&gt;die Entscheidung für die Verwendung von direct path FTS (oder IFFS) trifft nicht der CBO, sondern die run time engine und die Entscheidung wird für jedes Segment einzeln getroffen (also können die Partitionen eines partitionierten Objekts unterschiedlich behandelt werden).&lt;/li&gt;&lt;/ul&gt;Teil 2 - bis zur 90. Minute: &lt;br /&gt;&lt;ul&gt;&lt;li&gt;SYS.SEG$ ist die Tabelle, auf der DBA_SEGMENTS basiert.&lt;/li&gt;&lt;li&gt;Der Root-Block eines Index-Segments ist immer der erste Block nach dem Header.&lt;/li&gt;&lt;li&gt; In SEG$ finden sich die Positionen aller Segmente - aber wie wird SEG$ lokalisiert?&lt;/li&gt;&lt;li&gt;Dazu gibt es eine Tabelle SYS.BOOTSTRAP$, die DDL-Informationen zu diversen internen Tabellen enthält (wobei diese DDL nicht ausgeführt wird). In diesen DDL-Informationen sind File- und Blockangaben enthalten:&lt;/li&gt;&lt;/ul&gt;&lt;div class="codesnippet"&gt;&lt;pre&gt;select *&lt;br /&gt;  from sys.bootstrap$&lt;br /&gt; order by 1&lt;br /&gt;&lt;br /&gt;LINE#       OBJ# SQL_TEXT&lt;br /&gt;----- ---------- -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------&lt;br /&gt;   -1         -1 8.0.0.0.0&lt;br /&gt;    0          0 CREATE ROLLBACK SEGMENT SYSTEM STORAGE (  INITIAL 112K NEXT 56K MINEXTENTS 1 MAXEXTENTS 32765 OBJNO 0 EXTENTS (FILE 1 BLOCK 128))&lt;br /&gt;    2          2 CREATE CLUSTER C_OBJ#("OBJ#" NUMBER) PCTFREE 5 PCTUSED 40 INITRANS 2 MAXTRANS 255 STORAGE (  INITIAL 136K NEXT 200K MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0 OBJNO 2 EXTENTS (FILE 1 BLOCK 144)) SIZE 800&lt;br /&gt;    3          3 CREATE INDEX I_OBJ# ON CLUSTER C_OBJ# PCTFREE 10 INITRANS 2 MAXTRANS 255 STORAGE (  INITIAL 64K NEXT 1024K MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0 OBJNO 3 EXTENTS (FILE 1 BLOCK 168))&lt;br /&gt;    4          4 CREATE TABLE TAB$("OBJ#" NUMBER NOT NULL,"DATAOBJ#" NUMBER,"TS#" NUMBER NOT NULL,"FILE#" NUMBER NOT NULL,"BLOCK#" NUMBER NOT NULL,"BOBJ#" NUMBER,"TAB#" NUMBER,"COLS" NUMBER NOT NULL,"CLUCOLS" NUMBER,"PCTFREE$"&lt;br /&gt;    5          5 CREATE TABLE CLU$("OBJ#" NUMBER NOT NULL,"DATAOBJ#" NUMBER,"TS#" NUMBER NOT NULL,"FILE#" NUMBER NOT NULL,"BLOCK#" NUMBER NOT NULL,"COLS" NUMBER NOT NULL,"PCTFREE$" NUMBER NOT NULL,"PCTUSED$" NUMBER NOT NULL,"I&lt;br /&gt;    6          6 CREATE CLUSTER C_TS#("TS#" NUMBER) PCTFREE 10 PCTUSED 40 INITRANS 2 MAXTRANS 255 STORAGE (  INITIAL 64K NEXT 1024K MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0 OBJNO 6 EXTENTS (FILE 1 BLOCK 176))&lt;br /&gt;    7          7 CREATE INDEX I_TS# ON CLUSTER C_TS# PCTFREE 10 INITRANS 2 MAXTRANS 255 STORAGE (  INITIAL 64K NEXT 1024K MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0 OBJNO 7 EXTENTS (FILE 1 BLOCK 184))&lt;br /&gt;    8          8 CREATE CLUSTER C_FILE#_BLOCK#("TS#" NUMBER,"SEGFILE#" NUMBER,"SEGBLOCK#" NUMBER) PCTFREE 10 PCTUSED 40 INITRANS 2 MAXTRANS 255 STORAGE (  INITIAL 24K NEXT 1024K MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0&lt;br /&gt;    9          9 CREATE INDEX I_FILE#_BLOCK# ON CLUSTER C_FILE#_BLOCK# PCTFREE 10 INITRANS 2 MAXTRANS 255 STORAGE (  INITIAL 64K NEXT 1024K MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0 OBJNO 9 EXTENTS (FILE 1 BLOCK 200))&lt;br /&gt;   10         10 CREATE CLUSTER C_USER#("USER#" NUMBER) PCTFREE 10 PCTUSED 40 INITRANS 2 MAXTRANS 255 STORAGE (  INITIAL 64K NEXT 1024K MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0 OBJNO 10 EXTENTS (FILE 1 BLOCK 208)) SIZE&lt;br /&gt;   11         11 CREATE INDEX I_USER# ON CLUSTER C_USER# PCTFREE 10 INITRANS 2 MAXTRANS 255 STORAGE (  INITIAL 64K NEXT 1024K MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0 OBJNO 11 EXTENTS (FILE 1 BLOCK 216))&lt;br /&gt;   12         12 CREATE TABLE FET$("TS#" NUMBER NOT NULL,"FILE#" NUMBER NOT NULL,"BLOCK#" NUMBER NOT NULL,"LENGTH" NUMBER NOT NULL) STORAGE (  OBJNO 12 TABNO 1) CLUSTER C_TS#(TS#)&lt;br /&gt;   13         13 CREATE TABLE UET$("SEGFILE#" NUMBER NOT NULL,"SEGBLOCK#" NUMBER NOT NULL,"EXT#" NUMBER NOT NULL,"TS#" NUMBER NOT NULL,"FILE#" NUMBER NOT NULL,"BLOCK#" NUMBER NOT NULL,"LENGTH" NUMBER NOT NULL) STORAGE (  OBJNO&lt;br /&gt;   14         14 CREATE TABLE SEG$("FILE#" NUMBER NOT NULL,"BLOCK#" NUMBER NOT NULL,"TYPE#" NUMBER NOT NULL,"TS#" NUMBER NOT NULL,"BLOCKS" NUMBER NOT NULL,"EXTENTS" NUMBER NOT NULL,"INIEXTS" NUMBER NOT NULL,"MINEXTS" NUMBER NO&lt;br /&gt;   15         15 CREATE TABLE UNDO$("US#" NUMBER NOT NULL,"NAME" VARCHAR2(30) NOT NULL,"USER#" NUMBER NOT NULL,"FILE#" NUMBER NOT NULL,"BLOCK#" NUMBER NOT NULL,"SCNBAS" NUMBER,"SCNWRP" NUMBER,"XACTSQN" NUMBER,"UNDOSQN" NUMBER,&lt;br /&gt;   16         16 CREATE TABLE TS$("TS#" NUMBER NOT NULL,"NAME" VARCHAR2(30) NOT NULL,"OWNER#" NUMBER NOT NULL,"ONLINE$" NUMBER NOT NULL,"CONTENTS$" NUMBER NOT NULL,"UNDOFILE#" NUMBER,"UNDOBLOCK#" NUMBER,"BLOCKSIZE" NUMBER NOT&lt;br /&gt;   17         17 CREATE TABLE FILE$("FILE#" NUMBER NOT NULL,"STATUS$" NUMBER NOT NULL,"BLOCKS" NUMBER NOT NULL,"TS#" NUMBER,"RELFILE#" NUMBER,"MAXEXTEND" NUMBER,"INC" NUMBER,"CRSCNWRP" NUMBER,"CRSCNBAS" NUMBER,"OWNERINSTANCE"&lt;br /&gt;   18         18 CREATE TABLE OBJ$("OBJ#" NUMBER NOT NULL,"DATAOBJ#" NUMBER,"OWNER#" NUMBER NOT NULL,"NAME" VARCHAR2(30) NOT NULL,"NAMESPACE" NUMBER NOT NULL,"SUBNAME" VARCHAR2(30),"TYPE#" NUMBER NOT NULL,"CTIME" DATE NOT NULL&lt;br /&gt;   19         19 CREATE TABLE IND$("OBJ#" NUMBER NOT NULL,"DATAOBJ#" NUMBER,"TS#" NUMBER NOT NULL,"FILE#" NUMBER NOT NULL,"BLOCK#" NUMBER NOT NULL,"BO#" NUMBER NOT NULL,"INDMETHOD#" NUMBER NOT NULL,"COLS" NUMBER NOT NULL,"PCTF&lt;br /&gt;   20         20 CREATE TABLE ICOL$("OBJ#" NUMBER NOT NULL,"BO#" NUMBER NOT NULL,"COL#" NUMBER NOT NULL,"POS#" NUMBER NOT NULL,"SEGCOL#" NUMBER NOT NULL,"SEGCOLLENGTH" NUMBER NOT NULL,"OFFSET" NUMBER NOT NULL,"INTCOL#" NUMBER&lt;br /&gt;   21         21 CREATE TABLE COL$("OBJ#" NUMBER NOT NULL,"COL#" NUMBER NOT NULL,"SEGCOL#" NUMBER NOT NULL,"SEGCOLLENGTH" NUMBER NOT NULL,"OFFSET" NUMBER NOT NULL,"NAME" VARCHAR2(30) NOT NULL,"TYPE#" NUMBER NOT NULL,"LENGTH" N&lt;br /&gt;   22         22 CREATE TABLE USER$("USER#" NUMBER NOT NULL,"NAME" VARCHAR2(30) NOT NULL,"TYPE#" NUMBER NOT NULL,"PASSWORD" VARCHAR2(30),"DATATS#" NUMBER NOT NULL,"TEMPTS#" NUMBER NOT NULL,"CTIME" DATE NOT NULL,"PTIME" DATE,"E&lt;br /&gt;   23         23 CREATE TABLE PROXY_DATA$("CLIENT#" NUMBER NOT NULL,"PROXY#" NUMBER NOT NULL,"CREDENTIAL_TYPE#" NUMBER NOT NULL,"CREDENTIAL_VERSION#" NUMBER NOT NULL,"CREDENTIAL_MINOR#" NUMBER NOT NULL,"FLAGS" NUMBER NOT NULL)&lt;br /&gt;   24         24 CREATE UNIQUE INDEX I_PROXY_DATA$ ON PROXY_DATA$(CLIENT#,PROXY#) PCTFREE 10 INITRANS 2 MAXTRANS 255 STORAGE (  INITIAL 64K NEXT 1024K MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0 OBJNO 24 EXTENTS (FILE 1 B&lt;br /&gt;   25         25 CREATE TABLE PROXY_ROLE_DATA$("CLIENT#" NUMBER NOT NULL,"PROXY#" NUMBER NOT NULL,"ROLE#" NUMBER NOT NULL) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 STORAGE (  INITIAL 64K NEXT 1024K MINEXTENTS 1 MAXEXTENTS&lt;br /&gt;   26         26 CREATE INDEX I_PROXY_ROLE_DATA$_1 ON PROXY_ROLE_DATA$(CLIENT#,PROXY#) PCTFREE 10 INITRANS 2 MAXTRANS 255 STORAGE (  INITIAL 64K NEXT 1024K MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0 OBJNO 26 EXTENTS (FIL&lt;br /&gt;   27         27 CREATE UNIQUE INDEX I_PROXY_ROLE_DATA$_2 ON PROXY_ROLE_DATA$(CLIENT#,PROXY#,ROLE#) PCTFREE 10 INITRANS 2 MAXTRANS 255 STORAGE (  INITIAL 64K NEXT 1024K MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0 OBJNO 27&lt;br /&gt;   28         28 CREATE TABLE CON$("OWNER#" NUMBER NOT NULL,"NAME" VARCHAR2(30) NOT NULL,"CON#" NUMBER NOT NULL,"SPARE1" NUMBER,"SPARE2" NUMBER,"SPARE3" NUMBER,"SPARE4" VARCHAR2(1000),"SPARE5" VARCHAR2(1000),"SPARE6" DATE) PCT&lt;br /&gt;   29         29 CREATE CLUSTER C_COBJ#("OBJ#" NUMBER) PCTFREE 0 PCTUSED 50 INITRANS 2 MAXTRANS 255 STORAGE (  INITIAL 56K NEXT 1024K MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0 OBJNO 29 EXTENTS (FILE 1 BLOCK 296)) SIZE 3&lt;br /&gt;   30         30 CREATE INDEX I_COBJ# ON CLUSTER C_COBJ# PCTFREE 10 INITRANS 2 MAXTRANS 255 STORAGE (  INITIAL 64K NEXT 1024K MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0 OBJNO 30 EXTENTS (FILE 1 BLOCK 304))&lt;br /&gt;   31         31 CREATE TABLE CDEF$("CON#" NUMBER NOT NULL,"OBJ#" NUMBER NOT NULL,"COLS" NUMBER,"TYPE#" NUMBER NOT NULL,"ROBJ#" NUMBER,"RCON#" NUMBER,"RRULES" VARCHAR2(3),"MATCH#" NUMBER,"REFACT" NUMBER,"ENABLED" NUMBER,"CONDL&lt;br /&gt;   32         32 CREATE TABLE CCOL$("CON#" NUMBER NOT NULL,"OBJ#" NUMBER NOT NULL,"COL#" NUMBER NOT NULL,"POS#" NUMBER,"INTCOL#" NUMBER NOT NULL,"SPARE1" NUMBER,"SPARE2" NUMBER,"SPARE3" NUMBER,"SPARE4" VARCHAR2(1000),"SPARE5"&lt;br /&gt;   33         33 CREATE INDEX I_TAB1 ON TAB$(BOBJ#) PCTFREE 10 INITRANS 2 MAXTRANS 255 STORAGE (  INITIAL 64K NEXT 1024K MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0 OBJNO 33 EXTENTS (FILE 1 BLOCK 312))&lt;br /&gt;   34         34 CREATE UNIQUE INDEX I_UNDO1 ON UNDO$(US#) PCTFREE 10 INITRANS 2 MAXTRANS 255 STORAGE (  INITIAL 64K NEXT 1024K MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0 OBJNO 34 EXTENTS (FILE 1 BLOCK 320))&lt;br /&gt;   35         35 CREATE INDEX I_UNDO2 ON UNDO$(NAME) PCTFREE 10 INITRANS 2 MAXTRANS 255 STORAGE (  INITIAL 64K NEXT 1024K MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0 OBJNO 35 EXTENTS (FILE 1 BLOCK 328))&lt;br /&gt;   36         36 CREATE UNIQUE INDEX I_OBJ1 ON OBJ$(OBJ#,OWNER#,TYPE#) PCTFREE 10 INITRANS 2 MAXTRANS 255 STORAGE (  INITIAL 64K NEXT 1024K MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0 OBJNO 36 EXTENTS (FILE 1 BLOCK 336))&lt;br /&gt;   37         37 CREATE UNIQUE INDEX I_OBJ2 ON OBJ$(OWNER#,NAME,NAMESPACE,REMOTEOWNER,LINKNAME,SUBNAME,TYPE#,SPARE3,OBJ#) PCTFREE 10 INITRANS 2 MAXTRANS 255 STORAGE (  INITIAL 16K NEXT 104K MINEXTENTS 1 MAXEXTENTS 2147483645 P&lt;br /&gt;   38         38 CREATE INDEX I_OBJ3 ON OBJ$(OID$) PCTFREE 10 INITRANS 2 MAXTRANS 255 STORAGE (  INITIAL 64K NEXT 1024K MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0 OBJNO 38 EXTENTS (FILE 1 BLOCK 352))&lt;br /&gt;   39         39 CREATE INDEX I_OBJ4 ON OBJ$(DATAOBJ#,TYPE#,OWNER#) PCTFREE 10 INITRANS 2 MAXTRANS 255 STORAGE (  INITIAL 64K NEXT 1024K MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0 OBJNO 39 EXTENTS (FILE 1 BLOCK 360))&lt;br /&gt;   40         40 CREATE UNIQUE INDEX I_OBJ5 ON OBJ$(SPARE3,NAME,NAMESPACE,TYPE#,OWNER#,REMOTEOWNER,LINKNAME,SUBNAME,OBJ#) PCTFREE 10 INITRANS 2 MAXTRANS 255 STORAGE (  INITIAL 64K NEXT 1024K MINEXTENTS 1 MAXEXTENTS 2147483645&lt;br /&gt;   41         41 CREATE UNIQUE INDEX I_IND1 ON IND$(OBJ#) PCTFREE 10 INITRANS 2 MAXTRANS 255 STORAGE (  INITIAL 64K NEXT 1024K MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0 OBJNO 41 EXTENTS (FILE 1 BLOCK 376))&lt;br /&gt;   42         42 CREATE INDEX I_ICOL1 ON ICOL$(OBJ#) PCTFREE 10 INITRANS 2 MAXTRANS 255 STORAGE (  INITIAL 64K NEXT 1024K MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0 OBJNO 42 EXTENTS (FILE 1 BLOCK 384))&lt;br /&gt;   43         43 CREATE UNIQUE INDEX I_FILE1 ON FILE$(FILE#) PCTFREE 10 INITRANS 2 MAXTRANS 255 STORAGE (  INITIAL 64K NEXT 1024K MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0 OBJNO 43 EXTENTS (FILE 1 BLOCK 392))&lt;br /&gt;   44         44 CREATE UNIQUE INDEX I_FILE2 ON FILE$(TS#,RELFILE#) PCTFREE 10 INITRANS 2 MAXTRANS 255 STORAGE (  INITIAL 64K NEXT 1024K MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0 OBJNO 44 EXTENTS (FILE 1 BLOCK 400))&lt;br /&gt;   45         45 CREATE UNIQUE INDEX I_TS1 ON TS$(NAME) PCTFREE 10 INITRANS 2 MAXTRANS 255 STORAGE (  INITIAL 64K NEXT 1024K MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0 OBJNO 45 EXTENTS (FILE 1 BLOCK 408))&lt;br /&gt;   46         46 CREATE UNIQUE INDEX I_USER1 ON USER$(NAME) PCTFREE 10 INITRANS 2 MAXTRANS 255 STORAGE (  INITIAL 64K NEXT 1024K MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0 OBJNO 46 EXTENTS (FILE 1 BLOCK 416))&lt;br /&gt;   47         47 CREATE UNIQUE INDEX I_USER2 ON USER$(USER#,TYPE#,SPARE1,SPARE2) PCTFREE 10 INITRANS 2 MAXTRANS 255 STORAGE (  INITIAL 64K NEXT 1024K MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0 OBJNO 47 EXTENTS (FILE 1 BL&lt;br /&gt;   48         48 CREATE UNIQUE INDEX I_COL1 ON COL$(OBJ#,NAME) PCTFREE 10 INITRANS 2 MAXTRANS 255 STORAGE (  INITIAL 32K NEXT 104K MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0 OBJNO 48 EXTENTS (FILE 1 BLOCK 432))&lt;br /&gt;   49         49 CREATE INDEX I_COL2 ON COL$(OBJ#,COL#) PCTFREE 10 INITRANS 2 MAXTRANS 255 STORAGE (  INITIAL 32K NEXT 104K MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0 OBJNO 49 EXTENTS (FILE 1 BLOCK 440))&lt;br /&gt;   50         50 CREATE UNIQUE INDEX I_COL3 ON COL$(OBJ#,INTCOL#) PCTFREE 10 INITRANS 2 MAXTRANS 255 STORAGE (  INITIAL 32K NEXT 104K MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0 OBJNO 50 EXTENTS (FILE 1 BLOCK 448))&lt;br /&gt;   51         51 CREATE UNIQUE INDEX I_CON1 ON CON$(OWNER#,NAME) PCTFREE 10 INITRANS 2 MAXTRANS 255 STORAGE (  INITIAL 64K NEXT 1024K MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0 OBJNO 51 EXTENTS (FILE 1 BLOCK 456))&lt;br /&gt;   52         52 CREATE UNIQUE INDEX I_CON2 ON CON$(CON#) PCTFREE 10 INITRANS 2 MAXTRANS 255 STORAGE (  INITIAL 64K NEXT 1024K MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0 OBJNO 52 EXTENTS (FILE 1 BLOCK 464))&lt;br /&gt;   53         53 CREATE UNIQUE INDEX I_CDEF1 ON CDEF$(CON#) PCTFREE 10 INITRANS 2 MAXTRANS 255 STORAGE (  INITIAL 64K NEXT 1024K MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0 OBJNO 53 EXTENTS (FILE 1 BLOCK 472))&lt;br /&gt;   54         54 CREATE INDEX I_CDEF2 ON CDEF$(OBJ#) PCTFREE 10 INITRANS 2 MAXTRANS 255 STORAGE (  INITIAL 64K NEXT 1024K MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0 OBJNO 54 EXTENTS (FILE 1 BLOCK 480))&lt;br /&gt;   55         55 CREATE INDEX I_CDEF3 ON CDEF$(ROBJ#) PCTFREE 10 INITRANS 2 MAXTRANS 255 STORAGE (  INITIAL 64K NEXT 1024K MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0 OBJNO 55 EXTENTS (FILE 1 BLOCK 488))&lt;br /&gt;   56         56 CREATE INDEX I_CDEF4 ON CDEF$(ENABLED) PCTFREE 10 INITRANS 2 MAXTRANS 255 STORAGE (  INITIAL 64K NEXT 1024K MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0 OBJNO 56 EXTENTS (FILE 1 BLOCK 496))&lt;br /&gt;   57         57 CREATE INDEX I_CCOL1 ON CCOL$(CON#,COL#) PCTFREE 10 INITRANS 2 MAXTRANS 255 STORAGE (  INITIAL 64K NEXT 1024K MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0 OBJNO 57 EXTENTS (FILE 1 BLOCK 504))&lt;br /&gt;   58         58 CREATE UNIQUE INDEX I_CCOL2 ON CCOL$(CON#,INTCOL#) PCTFREE 10 INITRANS 2 MAXTRANS 255 STORAGE (  INITIAL 64K NEXT 1024K MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0 OBJNO 58 EXTENTS (FILE 1 BLOCK 512))&lt;br /&gt;   59         59 CREATE TABLE BOOTSTRAP$("LINE#" NUMBER NOT NULL,"OBJ#" NUMBER NOT NULL,"SQL_TEXT" VARCHAR2(4000) NOT NULL) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 STORAGE (  INITIAL 56K NEXT 1024K MINEXTENTS 1 MAXEXTENT&lt;/pre&gt;&lt;pre&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;&lt;li&gt;SYS.BOOTSTRAP$ wiederum wird durch den Header Block von File #1 lokalisiert (den man über das event file_hdrs dumpen kann; eine Liste der vorhandenen Dump-Events liefert dabei oradebug dumplist)&lt;/li&gt;&lt;li&gt;Die data_object_id identifiziert ein Segment, während die object_id das zugehörige logische Objekt angibt (und z.B. bei der Ermittlung von dependencies verwendet wird)&lt;/li&gt;&lt;ul&gt;&lt;li&gt;die data_object_id ist für die Tabellen in einem Cluster identisch.&lt;/li&gt;&lt;li&gt;sie ändert sich nach einem Neuaufbau (Index rebuild; Table move)&lt;/li&gt;&lt;li&gt;auch ein &lt;i&gt;truncate table&lt;/i&gt; ändert die data_object_id, da dadurch der segment header neu formatiert wird.&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Mit Hilfe eines refcursors kann man auch nach der Löschung einer Tabelle aus den Blocks Daten lesen! Das gilt selbst dann, wenn die Tabelle mit purge Option gelöscht wurde - sofern die Blocks nicht durch ein neues Segment überschrieben werden. Ursache dafür ist, dass das &lt;i&gt;drop table&lt;/i&gt; nur eine Änderung im Data Dictionary bewirkt. Allerdings funktioniert der refcursor-Zugriff nur so lange bis der nächste Zugriff auf den Segment Header erforderlich wird.&lt;/li&gt;&lt;li&gt;Ein Zugriff auf den refcursor nach einem &lt;i&gt;truncate table&lt;/i&gt; liefert den Fehler "ORA-08103: object no longer exists", da das truncate den Header neu formatiert (auch wenn man die Option &lt;i&gt;reuse storage&lt;/i&gt; verwendet)&lt;/li&gt;&lt;li&gt;Grundlage der Entscheidung, ob ein FTS über den Buffer Cache oder über DIRECT PATH READ erfolgt ist die _SMALL_TABLE_TRESHOLD&lt;/li&gt;&lt;ul&gt;&lt;li&gt;in 11.1 gilt, dass für ein Objekt, das &amp;gt; 5 * _SMALL_TABLE_TRESHOLD Blocks umfasst, der FTS über DIRECT PATH erfolgt, damit der Buffer Cache nicht mit nutzlosen Daten gefüllt wird; dabei ist die _SMALL_TABLE_TRESHOLD als 2% des Buffer Pool definiert.&lt;/li&gt;&lt;li&gt;für folgende Releases wird zusätzlich geprüft, wie viele Blocks des betroffenen Segments bereits im Cache vorliegen (Mit Hilfe von X$KCBOQH) und dieser Wert modifiziert dann die Threshold-Arithmetik (wenn das Objekt sowieso schon teilweise im Cache vorliegt, ist der DIRECT PATH Zugriff weniger interessant)&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-6245731422671048389?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/6245731422671048389/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2011/08/tanel-poder-uber-full-scans-und-direct.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/6245731422671048389'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/6245731422671048389'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2011/08/tanel-poder-uber-full-scans-und-direct.html' title='Tanel Poder über Full Scans und Direct Path Reads'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-6678402502317816138</id><published>2011-08-24T08:04:00.000-07:00</published><updated>2011-08-24T08:04:58.352-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Partitioning'/><title type='text'>Composite Partitionierung mit mehreren Ebenen</title><content type='html'>Dieser Tage beschäftige ich mich mit der Frage, wie man eine große Menge von Transaktionsdaten (ca. 5.000.000.000 Sätze) nach möglichst vielen Kriterien partitionieren kann. Nun habe ich in der Vergangenheit häufiger mit &lt;a href="http://download.oracle.com/docs/cd/E11882_01/server.112/e16541/partition.htm#i460895"&gt;&lt;i&gt;composite partitioning&lt;/i&gt;&lt;/a&gt; gearbeitet, um solche Daten zunächst zeitlich zu partitionieren und darunter dann nach Regionen oder Häusern zu subpartitionieren. Diesmal würde ich aber gerne noch eine dritte Ebene verwenden, nämlich die der Kunden - wobei in diesem Fall nur eine ganz grobe Zuordnung nach Transaktionen mit bzw. Transaktionen ohne Kundennummer erforderlich (und sinnvoll) wäre. Für meinen Test (in Version 11.2.0.1) verwende ich eine ganz einfache Tabelle mit drei Spalten (StoreId, CustomerId, SalesDate), die alle ihre Rolle bei der Partitionierung spielen sollen. Meine erste Wahl wäre eine Range-List-Partitionierung, da die Anzahl der gegebenen Stores nicht sehr groß ist und in einem Subpartition Template untergebracht werden kann:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;&lt;b&gt;Versuch 1: Range-List-Partitionierung mit zwei Spalten im Subpartition-Key&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="codesnippet"&gt;&lt;pre&gt;create table test_part_range_list&lt;br /&gt;( storeid number&lt;br /&gt;, salesdate date&lt;br /&gt;, customerid number&lt;br /&gt;, customerflag number generated always as (case when customerid = 0 then 0 else 1 end ))&lt;br /&gt;   partition by range (salesdate)&lt;br /&gt;   subpartition by list (storeid, customerflag)&lt;br /&gt;   subpartition template&lt;br /&gt;      (subpartition sp1_cust values (1, 1)&lt;br /&gt;      , subpartition sp2_cust values (2, 1)&lt;br /&gt;      , subpartition sp1_nocust values (1, 0)&lt;br /&gt;      , subpartition sp2_nocust values (2, 0)&lt;br /&gt;      , subpartition sp_others values (default )&lt;br /&gt;      )&lt;br /&gt;  (partition p1 values less than ( to_date('01.01.2011','dd.mm.yyyy')),&lt;br /&gt;   partition p2 values less than ( to_date('01.02.2011','dd.mm.yyyy'))&lt;br /&gt;  )&lt;br /&gt;;&lt;br /&gt;&lt;br /&gt;   subpartition template&lt;br /&gt;   *&lt;br /&gt;FEHLER in Zeile 8:&lt;br /&gt;ORA-14304: List-Partitionierungsmethode erwartet eine einzelne Partitionierungsspalte&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;Und schon zeigt sich, dass es bisweilen ratsam ist, die Dokumentation etwas genauer anzuschauen: List-Partitionierung funktioniert offenbar nur mit einer einzelnen Schlüsselspalte, was diesen Versuch beendet...&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: large;"&gt;&lt;b&gt;Versuch 2: Range-List-Partitionierung mit einer virtuellen Spalte im Subpartition-Key&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Im ersten Versuch hatte ich bereits eine virtuelle Spalte verwendet, um die Fallunterscheidung zwischen Transaktion mit Kundennummer und Transaktion ohne Kundennummer unterzubringen - ohne dafür eine "echte" Spalte definieren zu müssen, die die Breite der Sätze erhöhen würde. &lt;i&gt;Virtual Column-Based Partitioning&lt;a href="http://download.oracle.com/docs/cd/E11882_01/server.112/e16541/partition.htm#CACFEGDG"&gt;&lt;/a&gt;&lt;/i&gt; ist ein neues Feature in Version 11, scheint aber problemlos zu funktionieren.&lt;br /&gt;&lt;br /&gt;&lt;div class="codesnippet"&gt;&lt;pre&gt;create table test_part_range_list&lt;br /&gt;( storeid number&lt;br /&gt;, salesdate date&lt;br /&gt;, customerid number&lt;br /&gt;, subpartcode number generated always as (case when customerid = 0 then storeid * 100 + 1 else storeid * 100 end ))&lt;br /&gt;   partition by range (salesdate)&lt;br /&gt;   subpartition by list (subpartcode)&lt;br /&gt;   subpartition template&lt;br /&gt;      (subpartition st1_nocust values (100)&lt;br /&gt;      , subpartition st1_cust values (101)&lt;br /&gt;      , subpartition st2_nocust values (200)&lt;br /&gt;      , subpartition st2_cust values (201)&lt;br /&gt;      , subpartition sp_others values (default )&lt;br /&gt;      )&lt;br /&gt;  (partition p1 values less than ( to_date('01.01.2011','dd.mm.yyyy')),&lt;br /&gt;   partition p2 values less than ( to_date('01.02.2011','dd.mm.yyyy'))&lt;br /&gt;  );&lt;br /&gt;&lt;br /&gt;-- Testdaten&lt;br /&gt;insert into test_part_range_list (storeid, salesdate, customerid)&lt;br /&gt;values (1, '31.12.2010', 4711);  &lt;br /&gt;&lt;br /&gt;insert into test_part_range_list (storeid, salesdate, customerid)&lt;br /&gt;values (1, '31.12.2010', 0);  &lt;br /&gt;&lt;br /&gt;insert into test_part_range_list (storeid, salesdate, customerid)&lt;br /&gt;values (1, '31.01.2011', 4711);  &lt;br /&gt;&lt;br /&gt;insert into test_part_range_list (storeid, salesdate, customerid)&lt;br /&gt;values (1, '31.01.2011', 0);  &lt;br /&gt;&lt;br /&gt;insert into test_part_range_list (storeid, salesdate, customerid)&lt;br /&gt;values (2, '31.12.2010', 1234);  &lt;br /&gt;&lt;br /&gt;insert into test_part_range_list (storeid, salesdate, customerid)&lt;br /&gt;values (2, '31.12.2010', 0);  &lt;br /&gt;&lt;br /&gt;insert into test_part_range_list (storeid, salesdate, customerid)&lt;br /&gt;values (2, '31.01.2011', 1234);  &lt;br /&gt;&lt;br /&gt;insert into test_part_range_list (storeid, salesdate, customerid)&lt;br /&gt;values (2, '31.01.2011', 0);  &lt;br /&gt;&lt;br /&gt;-- Statistikerhebung auf Subpartitionsebene&lt;br /&gt;exec dbms_stats.gather_table_stats(user, 'TEST_PART_RANGE_LIST', Granularity =&gt; 'SUBPARTITION')&lt;br /&gt;&lt;br /&gt;-- Verteilung der Sätze auf die Subpartitionen&lt;br /&gt;select partition_name&lt;br /&gt;     , subpartition_name&lt;br /&gt;     , num_rows &lt;br /&gt;  from dba_tab_subpartitions &lt;br /&gt; where table_name = 'TEST_PART_RANGE_LIST';  &lt;br /&gt;&lt;br /&gt;PARTITION_NAME                 SUBPARTITION_NAME                NUM_ROWS&lt;br /&gt;------------------------------ ------------------------------ ----------&lt;br /&gt;P1                             P1_ST1_NOCUST                           1&lt;br /&gt;P1                             P1_ST1_CUST                             1&lt;br /&gt;P1                             P1_ST2_NOCUST                           1&lt;br /&gt;P1                             P1_ST2_CUST                             1&lt;br /&gt;P1                             P1_SP_OTHERS                            0&lt;br /&gt;P2                             P2_ST1_NOCUST                           1&lt;br /&gt;P2                             P2_ST1_CUST                             1&lt;br /&gt;P2                             P2_ST2_NOCUST                           1&lt;br /&gt;P2                             P2_ST2_CUST                             1&lt;br /&gt;P2                             P2_SP_OTHERS                            0&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;Die Partitionierung führt also zunächst zur gewünschten Verteilung der Daten auf die Partitionen (wobei die Default-Sub-Partitionen leer bleiben; in ihnen landen alle Sätze, für die im Subpartition Template keine eigene (Sub-)Partition definiert ist. Nun aber zur Frage, ob diese Partitionierung sinnvolles &lt;i&gt;Partition Pruning&lt;/i&gt; erlaubt - also den Ausschluss von Partitionen, die keine relevanten Daten enthalten, im Rahmen der Abarbeitung entsprechender Queries. Dazu liefert Autotrace folgende Ergebnisse:&lt;br /&gt;&lt;br /&gt;&lt;div class="codesnippet"&gt;&lt;pre&gt;select *&lt;br /&gt;  from test_part_range_list&lt;br /&gt;&lt;br /&gt;   STOREID SALESDAT CUSTOMERID SUBPARTCODE&lt;br /&gt;---------- -------- ---------- -----------&lt;br /&gt;         1 31.12.10       4711         100&lt;br /&gt;         1 31.12.10          0         101&lt;br /&gt;         2 31.12.10       1234         200&lt;br /&gt;         2 31.12.10          0         201&lt;br /&gt;         1 31.01.11       4711         100&lt;br /&gt;         1 31.01.11          0         101&lt;br /&gt;         2 31.01.11       1234         200&lt;br /&gt;         2 31.01.11          0         201&lt;br /&gt;&lt;br /&gt;8 Zeilen ausgewõhlt.&lt;br /&gt;&lt;br /&gt;Abgelaufen: 00:00:00.04&lt;br /&gt;&lt;br /&gt;Ausführungsplan&lt;br /&gt;----------------------------------------------------------&lt;br /&gt;Plan hash value: 1185884213&lt;br /&gt;&lt;br /&gt;------------------------------------------------------------------------------------------------------------&lt;br /&gt;| Id  | Operation           | Name                 | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |&lt;br /&gt;------------------------------------------------------------------------------------------------------------&lt;br /&gt;|   0 | SELECT STATEMENT    |                      |     8 |   136 |    21   (0)| 00:00:01 |       |       |&lt;br /&gt;|   1 |  PARTITION RANGE ALL|                      |     8 |   136 |    21   (0)| 00:00:01 |     1 |     2 |&lt;br /&gt;|   2 |   PARTITION LIST ALL|                      |     8 |   136 |    21   (0)| 00:00:01 |     1 |     5 |&lt;br /&gt;|   3 |    TABLE ACCESS FULL| TEST_PART_RANGE_LIST |     8 |   136 |    21   (0)| 00:00:01 |     1 |    10 |&lt;br /&gt;------------------------------------------------------------------------------------------------------------&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Statistiken&lt;br /&gt;----------------------------------------------------------&lt;br /&gt;          0  recursive calls&lt;br /&gt;          0  db block gets&lt;br /&gt;         62  consistent gets&lt;br /&gt;          0  physical reads&lt;br /&gt;          0  redo size&lt;br /&gt;        917  bytes sent via SQL*Net to client&lt;br /&gt;        520  bytes received via SQL*Net from client&lt;br /&gt;          2  SQL*Net roundtrips to/from client&lt;br /&gt;          0  sorts (memory)&lt;br /&gt;          0  sorts (disk)&lt;br /&gt;          8  rows processed&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;Diese 62 consistent gets sind also der Referenzwert für das Lesen aller Partitionen. Die folgenden Autotrace-Listings sind aus Gründen der Übersichtlichkeit massiv gekürzt:&lt;br /&gt;&lt;br /&gt;&lt;div class="codesnippet"&gt;&lt;pre&gt;-- Datumseinschränkung&lt;br /&gt;select *&lt;br /&gt;  from test_part_range_list&lt;br /&gt; where salesdate = '31.12.2010';&lt;br /&gt;&lt;br /&gt;------------------------------------------------------------------------------&lt;br /&gt;| Id  | Operation              | Name                 | Rows | Pstart| Pstop |&lt;br /&gt;------------------------------------------------------------------------------&lt;br /&gt;|   0 | SELECT STATEMENT       |                      |     4|       |       |&lt;br /&gt;|   1 |  PARTITION RANGE SINGLE|                      |     4|     1 |     1 |&lt;br /&gt;|   2 |   PARTITION LIST ALL   |                      |     4|     1 |     5 |&lt;br /&gt;|*  3 |    TABLE ACCESS FULL   | TEST_PART_RANGE_LIST |     4|     1 |     5 |&lt;br /&gt;-------------------------------------------------------------------------------&lt;br /&gt;&lt;br /&gt;Statistiken&lt;br /&gt;----------------------------------------------------------&lt;br /&gt;         33  consistent gets&lt;br /&gt;          4  rows processed&lt;br /&gt;&lt;br /&gt;--&gt; partition pruning funktioniert (was auf dieser Ebene keine Überraschung ist)&lt;br /&gt;&lt;br /&gt;-- Einschränkung auf StoreId&lt;br /&gt;select *&lt;br /&gt;  from test_part_range_list&lt;br /&gt; where storeid = 1;&lt;br /&gt;&lt;br /&gt;----------------------------------------------------------------------------&lt;br /&gt;| Id  | Operation           | Name                 | Rows  | Pstart| Pstop |&lt;br /&gt;----------------------------------------------------------------------------&lt;br /&gt;|   0 | SELECT STATEMENT    |                      |     4 |       |       |&lt;br /&gt;|   1 |  PARTITION RANGE ALL|                      |     4 |     1 |     2 |&lt;br /&gt;|   2 |   PARTITION LIST ALL|                      |     4 |     1 |     5 |&lt;br /&gt;|*  3 |    TABLE ACCESS FULL| TEST_PART_RANGE_LIST |     4 |     1 |    10 |&lt;br /&gt;----------------------------------------------------------------------------		  &lt;br /&gt;&lt;br /&gt;Statistiken&lt;br /&gt;----------------------------------------------------------&lt;br /&gt;         62  consistent gets&lt;br /&gt;          4  rows processed	  &lt;br /&gt;&lt;br /&gt;--&gt; kein Pruning: PARTITION RANGE ALL und PARTITION LIST ALL&lt;br /&gt;--&gt; offenbar kann der Wert der virtuellen Spalte subpartcode nicht aus&lt;br /&gt;    der StoreId abgeleitet werden&lt;br /&gt;&lt;br /&gt;-- Einschränkung auf CustomerId&lt;br /&gt;select *&lt;br /&gt;  from test_part_range_list&lt;br /&gt; where customerid = 4711;&lt;br /&gt;&lt;br /&gt;----------------------------------------------------------------------------&lt;br /&gt;| Id  | Operation           | Name                 | Rows  | Pstart| Pstop |&lt;br /&gt;----------------------------------------------------------------------------&lt;br /&gt;|   0 | SELECT STATEMENT    |                      |     3 |       |       |&lt;br /&gt;|   1 |  PARTITION RANGE ALL|                      |     3 |     1 |     2 |&lt;br /&gt;|   2 |   PARTITION LIST ALL|                      |     3 |     1 |     5 |&lt;br /&gt;|*  3 |    TABLE ACCESS FULL| TEST_PART_RANGE_LIST |     3 |     1 |    10 |&lt;br /&gt;----------------------------------------------------------------------------		  &lt;br /&gt;&lt;br /&gt;Statistiken&lt;br /&gt;----------------------------------------------------------&lt;br /&gt;         62  consistent gets&lt;br /&gt;          2  rows processed&lt;br /&gt;&lt;br /&gt;--&gt; gleiches Verhalten wie bei der StoreId, was wiederum konsequent ist&lt;br /&gt;&lt;br /&gt;-- Kombinierte Bedingung mit StoreId und CustomerId&lt;br /&gt;select *&lt;br /&gt;  from test_part_range_list&lt;br /&gt; where storeid = 1&lt;br /&gt;   and customerid = 4711;&lt;br /&gt;&lt;br /&gt;----------------------------------------------------------------------------&lt;br /&gt;| Id  | Operation           | Name                 | Rows  | Pstart| Pstop |&lt;br /&gt;----------------------------------------------------------------------------&lt;br /&gt;|   0 | SELECT STATEMENT    |                      |     1 |       |       |&lt;br /&gt;|   1 |  PARTITION RANGE ALL|                      |     1 |     1 |     2 |&lt;br /&gt;|   2 |   PARTITION LIST ALL|                      |     1 |     1 |     5 |&lt;br /&gt;|*  3 |    TABLE ACCESS FULL| TEST_PART_RANGE_LIST |     1 |     1 |    10 |&lt;br /&gt;----------------------------------------------------------------------------&lt;br /&gt;&lt;br /&gt;Statistiken&lt;br /&gt;----------------------------------------------------------&lt;br /&gt;         62  consistent gets&lt;br /&gt;          2  rows processed		  &lt;br /&gt;&lt;br /&gt;--&gt; auch die Kombination der beiden Basiswerte, aus denen sich die virtuelle&lt;br /&gt;    Partitionsschlüsselspalte definiert, führt nicht zum Partition Pruning&lt;br /&gt;&lt;br /&gt;-- Bedinung mit der virtuellen Subpartitionsspalte&lt;br /&gt;select *&lt;br /&gt;  from test_part_range_list&lt;br /&gt; where subpartcode = 201;&lt;br /&gt;&lt;br /&gt;-------------------------------------------------------------------------------&lt;br /&gt;| Id  | Operation              | Name                 | Rows  | Pstart| Pstop |&lt;br /&gt;-------------------------------------------------------------------------------&lt;br /&gt;|   0 | SELECT STATEMENT       |                      |     2 |       |       |&lt;br /&gt;|   1 |  PARTITION RANGE ALL   |                      |     2 |     1 |     2 |&lt;br /&gt;|   2 |   PARTITION LIST SINGLE|                      |     2 |   KEY |   KEY |&lt;br /&gt;|   3 |    TABLE ACCESS FULL   | TEST_PART_RANGE_LIST |     2 |   KEY |   KEY |&lt;br /&gt;-------------------------------------------------------------------------------&lt;br /&gt;&lt;br /&gt;Statistiken&lt;br /&gt;----------------------------------------------------------&lt;br /&gt;         16  consistent gets&lt;br /&gt;          2  rows processed&lt;br /&gt;&lt;br /&gt;--&gt; mit dem virtuellen subpartcode funktioniert das Pruning&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;Demnach sorgt die virtuelle Spalte "subpartcode" zwar für eine sinnvolle Verteilung der Daten auf die Subpartitionen, aber das Partition Pruning funktioniert auf Subpartitionsebene nur, wenn dieses Attribut auch als Bedingung in den zugehörigen Queries erscheint. Damit ist aber auch dieser zweite Fall nur noch von akademischem Interesse, da die Queries, die auf den Daten operieren sollen, nicht notwenig beide Einschränkungen enthalten - und schon gar nicht die virtuelle Zusatzspalte verwenden.&lt;br /&gt;&lt;br /&gt;Da der Eintrag jetzt schon recht unübersichtlich geworden ist, verschiebe ich weitere Untersuchungen (Hash-Subpartitioning, Range-Partitioning mit mehreren Spalten) auf ein andermal.&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-6678402502317816138?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/6678402502317816138/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2011/08/composite-partitionierung-mit-mehreren.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/6678402502317816138'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/6678402502317816138'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2011/08/composite-partitionierung-mit-mehreren.html' title='Composite Partitionierung mit mehreren Ebenen'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-8138715851003439353</id><published>2011-08-23T12:39:00.000-07:00</published><updated>2011-08-23T12:39:09.332-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PL/SQL'/><title type='text'>PL/SQL Mythen</title><content type='html'>Morten Braten räumt in seinem &lt;a href="http://ora-00001.blogspot.com/2011/07/mythbusters-stored-procedures-edition.html"&gt;Blog&lt;/a&gt; mit allerlei falschen Vorstellungen auf, die über den Einsatz von PL/SQL existieren.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-8138715851003439353?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/8138715851003439353/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2011/08/plsql-mythen.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/8138715851003439353'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/8138715851003439353'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2011/08/plsql-mythen.html' title='PL/SQL Mythen'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-5711699957406308106</id><published>2011-08-19T06:14:00.000-07:00</published><updated>2011-08-19T06:16:25.915-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Trace'/><title type='text'>gather_plan_statistics</title><content type='html'>Dass die Erfassung von Ausführungsstatistiken mit Hilfe des gather_plan_statistics Hints (oder Setzung von statistics_level=all) einen relativ großen Einfluß auf die Performance von Queries besitzt, hatte ich schon häufiger festgestellt. In Jonathan Lewis' &lt;a href="http://jonathanlewis.wordpress.com/2007/11/25/gather_plan_statistics/"&gt;Blog&lt;/a&gt; findet man dazu eine Erklärung: verantwortlich ist offenbar vor allem die &lt;i&gt;timer&lt;/i&gt; Funktion des verwendeten Betriebssystems.&lt;br /&gt;&lt;br /&gt;Was man mit den Statistiken anfangen kann, erläutert &lt;a href="http://blogs.oracle.com/optimizer/entry/how_do_i_know_if"&gt;Maria Colgan&lt;/a&gt; dieser Tage - und ihrem Artikel verdanke ich auch den Link auf den Scratchpad-Artikel. &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-5711699957406308106?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/5711699957406308106/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2011/08/gatherplanstatistics.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/5711699957406308106'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/5711699957406308106'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2011/08/gatherplanstatistics.html' title='gather_plan_statistics'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-8704309141019732650</id><published>2011-08-19T05:34:00.000-07:00</published><updated>2011-08-21T10:07:59.987-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Join'/><category scheme='http://www.blogger.com/atom/ns#' term='Buffer Cache'/><title type='text'>Logical I/O Optimization</title><content type='html'>Noch mal ein Link auf Randolf Geists Blog: &lt;a href="http://oracle-randolf.blogspot.com/2011/08/logical-io-evolution-part-3-11g.html"&gt;Logical I/O Evolution - Part 3: 11g&lt;/a&gt;. Zum Artikel lässt sich sagen, dass:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;er ziemlich lang ist, was dem Autor auch aufgefallen zu sein scheint ... &lt;/li&gt;&lt;li&gt;er eine umfassende Untersuchung der in 11g verfügbaren Optimierungen enthält.&lt;/li&gt;&lt;li&gt;man in 11g die Gestalt eines Nested Loops über die Parameter [NO_]NLJ_BATCHING und [NO_]NLJ_PREFETCH steuern kann. Ein paar Links zum &lt;i&gt;Nested Loop Join Batching&lt;/i&gt; hatte ich vor einigen Monaten &lt;a href="http://martinpreiss.blogspot.com/2011/03/nested-loops-optimierung-in-11g.html"&gt;hier&lt;/a&gt; gesammelt.&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/li&gt;&lt;li&gt;die LIO-Optimierungen in 11g auch ohne &lt;i&gt;Table Prefetching&lt;/i&gt; und &lt;i&gt;Nested Loop Join Batching&lt;/i&gt; verfügbar sind (und ohne &lt;i&gt;fastpath consistent gets&lt;/i&gt;).&lt;/li&gt;&lt;li&gt;die Optimierung stark von der physikalischen Sortierung der Daten abhängt.&lt;/li&gt;&lt;li&gt;das massive Pinning der Blöcke in der optimierten Version anscheinend keine deutlich negative Wirkung auf die Concurrency hat.&lt;/li&gt;&lt;/ul&gt;Gelegentlich sollte ich den Artikel noch mal lesen, um die Details halbwegs zu fassen ...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-8704309141019732650?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/8704309141019732650/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2011/08/logical-io-optimization.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/8704309141019732650'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/8704309141019732650'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2011/08/logical-io-optimization.html' title='Logical I/O Optimization'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-1362664818181697107</id><published>2011-08-19T00:47:00.000-07:00</published><updated>2011-08-19T00:47:47.947-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Trace'/><title type='text'>Optimizer Trace</title><content type='html'>&lt;a href="http://structureddata.org/2011/08/18/creating-optimizer-trace-files/"&gt;Greg Rahn&lt;/a&gt; erläutert einige neue Varianten zur Erstellung von Optimizer Traces in 11g, denn dort gibt es neben Event 10053 noch ein paar andere Möglichkeiten.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-1362664818181697107?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/1362664818181697107/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2011/08/optimizer-trace.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/1362664818181697107'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/1362664818181697107'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2011/08/optimizer-trace.html' title='Optimizer Trace'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-8148492599743446706</id><published>2011-08-19T00:06:00.000-07:00</published><updated>2011-08-31T00:25:17.046-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Trace'/><title type='text'>DBMS_XPLAN in RAC-Datenbanken</title><content type='html'>Dieser Tage habe ich in Jonathan Lewis' Blog &lt;a href="http://jonathanlewis.wordpress.com/2011/08/16/dbms_xplan-4/#comment-41320"&gt;eine Frage&lt;/a&gt; nach der Verwendbarkeit von dbms_xplan.display_cursor in RAC-Systemen gestellt, aber zunächst nur einen kurzen Kommentar von Dom Brooks dazu bekommen. Da sich im Thread neben dem Herrn Lewis auch noch die Herren Geist und Rahn aufgehalten haben, hoffe ich darauf, dass da vielleicht noch weitere Bemerkungen folgen. Für's erste aber noch mal meine Beobachtungen:&lt;br /&gt;&lt;br /&gt;Beim Versuch, in einer RAC-Datenbank den Zugriffsplan für eine über gv$sql ermittelte sql_id mit Hilfe von dbms_xplan.display_cursor anzeigen zu lassen, bekomme ich kein Ergebnis:&lt;br /&gt;&lt;br /&gt;&lt;div class="codesnippet"&gt;&lt;pre&gt;select *&lt;br /&gt;  from table(dbms_xplan.display_cursor(sql_id =&amp;gt; '13x0qwkc4xrfv', cursor_child_no=&amp;gt;1));&lt;br /&gt; &lt;br /&gt;PLAN_TABLE_OUTPUT&lt;br /&gt;---------------------------------------------------------------------------------------------------&lt;br /&gt;SQL_ID: 13x0qwkc4xrfv, child number: 1 cannot be found&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;In v$sql_plan sehe ich auch keine zugehörigen Einträge, aber in gv$sql_plan finden sich die gesuchten Informationen:&lt;br /&gt;&lt;br /&gt;&lt;div class="codesnippet"&gt;&lt;pre&gt;select count(*)&lt;br /&gt;  from v$sql_plan&lt;br /&gt; where sql_id = '13x0qwkc4xrfv'&lt;br /&gt;   and child_number = 1;&lt;br /&gt; &lt;br /&gt;  COUNT(*)&lt;br /&gt;----------&lt;br /&gt;         0&lt;br /&gt; &lt;br /&gt;select count(*)&lt;br /&gt;  from gv$sql_plan&lt;br /&gt; where sql_id = '13x0qwkc4xrfv'&lt;br /&gt;   and child_number = 1;&lt;br /&gt; &lt;br /&gt;  COUNT(*)&lt;br /&gt;----------&lt;br /&gt;         4&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;Offenbar greift dbms_xplan.display_cursor nicht auf die gv$-Views zu: in einer anderen Datenbank (kein RAC), sehe ich über Event 10046 nur rekursive Zugriffe auf v$-Views:&lt;br /&gt;&lt;br /&gt;&lt;div class="codesnippet"&gt;&lt;pre&gt;select /* EXEC_FROM_DBMS_XPLAN */ case when upper(sql_text) like&lt;br /&gt;  '%DBMS_XPLAN%' then 0 else 1 end case, SQL_ID, child_number&lt;br /&gt;from&lt;br /&gt; v$sql where SQL_ID ='8szmwam7fysa3' and child_number =0&lt;br /&gt; &lt;br /&gt;...&lt;br /&gt; &lt;br /&gt;Parsing user id: 68     (recursive depth: 1)&lt;br /&gt; &lt;br /&gt;Rows     Row Source Operation&lt;br /&gt;-------  ---------------------------------------------------&lt;br /&gt;      1  FIXED TABLE FIXED INDEX X$KGLCURSOR_CHILD (ind:2) (cr=0 pr=0 pw=0 time=0 us cost=0 size=536 card=1)&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;Das entspricht auch den Angaben der &lt;a href="http://download.oracle.com/docs/cd/B28359_01/appdev.111/b28419/d_xplan.htm#CACFJGHG"&gt;Doku&lt;/a&gt;: "The table function DISPLAY_CURSOR requires to have select privileges on the following fixed views: V$SQL_PLAN, V$SESSION and V$SQL_PLAN_STATISTICS_ALL". Im Widerspruch dazu scheint mir der entsprechende &lt;a href="http://www.morganslibrary.org/reference/pkgs/dbms_xplan.html#dxdc"&gt;Eintrag in Morgan's Library&lt;/a&gt; zu sein: "Display from GV$SQL_PLAN (or GV$SQL_PLAN_STATISTICS_ALL)."&lt;br /&gt;&lt;br /&gt;Meiner Meinung nach wäre es günstig, wenn dbms_xplan.display_cursor einen NODE-Parameter beinhalten würde, da die Plan-Informationen über gv$_sql_plan ja offenbar verfügbar wären.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Nachtrag 31.08.2011&lt;/b&gt;: in einem &lt;a href="http://jonathanlewis.wordpress.com/2011/08/16/dbms_xplan-4/#comment-41573"&gt;Kommentar&lt;/a&gt; im Sratchpad wurde ein funktionierender Workaround vorgeschlagen, der die Anzeige der Pläne von anderen Knoten ermöglicht:&lt;br /&gt;&lt;div class="codesnippet"&gt;&lt;pre&gt;select * &lt;br /&gt;  from table(dbms_xplan.display('gv$sql_plan_statistics_all'&lt;br /&gt;                               , null&lt;br /&gt;                               , null&lt;br /&gt;                               , 'inst_id = &amp;inst_id and sql_id = ''&amp;sql_id'' and child_number = &amp;child_number')&lt;br /&gt;             );&lt;br /&gt;&lt;/div&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-8148492599743446706?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/8148492599743446706/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2011/08/dbmsxplan-in-rac-datenbanken.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/8148492599743446706'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/8148492599743446706'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2011/08/dbmsxplan-in-rac-datenbanken.html' title='DBMS_XPLAN in RAC-Datenbanken'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-117241333009694313</id><published>2011-08-18T23:33:00.000-07:00</published><updated>2011-08-26T07:02:21.304-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Redo'/><title type='text'>LWGR und Commit</title><content type='html'>Jonathan Lewis beschreibt in seinem &lt;a href="http://jonathanlewis.wordpress.com/2011/08/19/redo-2/"&gt;Blog&lt;/a&gt; ein recht seltsames (und potentiell gefährliches) Verhalten des Oracle Servers: wenn eine Transaktion ein Commit durchführt und die Information im Log Buffer landet, dann wird sie für andere Sessions sichtbar - auch dann, wenn der LWGR nicht mehr dazu in der Lage ist, die Commit-Informationen in die Redo Log Dateien zu schreiben. Nach einem Neustart wird diese Transaktion aber nicht als commited betrachtet, da eben die persistierten Log-Informationen fehlen.&lt;br /&gt;&lt;br /&gt;Dieses Verhalten widerspricht allem, was ich bisher zum Thema gelesen hatte, denn ich ging davon aus, dass die Festschreibung in den redo Logs zum erfolgreichen Commit gehört. Da der Herr Lewis den Sachverhalt aber in mehreren Releases ab 8.1 reproduzieren konnte, ist das offenbar schon seit langer Zeit so gewesen.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Nachtrag 26.08.2011&lt;/b&gt;: zu Jonathan Lewis' Artikel gibt's inzwischen 69 Kommentare und ein umfangreiches Update und Tony Hasler, der das Problem als erster beschrieben hatte, hat noch &lt;a href="http://tonyhasler.wordpress.com/2011/08/24/acid-and-tpc-c/"&gt;zwei&lt;/a&gt; &lt;a href="http://tonyhasler.wordpress.com/2011/08/22/why-is-acid-important/"&gt;Artikel&lt;/a&gt; zur Frage beigesteuert, was dieses Verhalten für Oracles Verhältnis zu ACID bedeutet.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-117241333009694313?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/117241333009694313/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2011/08/lwgr-und-commit.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/117241333009694313'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/117241333009694313'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2011/08/lwgr-und-commit.html' title='LWGR und Commit'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-7009565015101319375</id><published>2011-08-17T01:14:00.000-07:00</published><updated>2011-08-17T01:14:49.796-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Subquery Factoring'/><category scheme='http://www.blogger.com/atom/ns#' term='SQL Server'/><title type='text'>SSAS und Subquery Factoring</title><content type='html'>Gestern ist einem meiner Kollegen folgendes Problem begegnet: eine Query mit exzessivem &lt;i&gt;Subquery Factoring&lt;/i&gt; (also vielen Abfrageblöcken im WITH) lief problemlos und ließ sich auch problemlos in einer View verwenden. Nach Einbindung in die DataSourceView eines SSAS-Projekts brachte das Processing eines auf der View basierenden Objekts dann aber die folgende Fehlermeldung (bzw. die deutschsprachige Version dazu):&lt;br /&gt;&lt;br /&gt;&lt;div class="codesnippet"&gt;&lt;pre&gt;ORA-32036: unsupported case for inlining of query name in WITH clause&lt;br /&gt;&lt;/div&gt;&lt;/pre&gt;&lt;br /&gt;Über Google landeten wir dann schnell bei Dom Brooks, der das Thema gelegentlich in seinem &lt;a href="http://orastory.wordpress.com/2007/09/20/one-of-those-weird-ones-ora-32036/"&gt;Blog&lt;/a&gt; beleuchtet hat: "According to a couple of metalink articles, the feature/bug/issue/problem is that SQL*Plus, Toad and SQLDeveloper are not reporting the error, rather than the correct behaviour as per ODBC or any other driver raising the error." Dort findet man dann neben den Links auf MOS in einem der Kommentare auch noch einen Workaround, mit dem wir vermeiden konnten, die (halbwegs) übersichtliche View noch einmal komplett neu zu definieren: nämlich die Verwendung des Parameters DistribTx=0 im Connection String der DataSource, mit dem man die Verwendung von verteilten Transaktionen deaktiviert - wobei ich nicht behaupten will, den inneren Zusammenhang von Subquery Factoring und Distributed Transactions im Detail verstanden zu haben ...  &lt;br /&gt;&lt;br /&gt;Grundsätzlich scheint es doch noch ein paar Fälle zu geben, in denen &lt;i&gt;Subquery Factoring&lt;/i&gt; nicht ganz so stabil funktioniert wie entsprechende Inline Views. Vermutlich ist das ein ähnlicher Fall wie der der ANSI-Join-Syntax, die bei Oracle ja auch noch nicht ganz so solide ist wie die traditionelle Schreibweise, obwohl auch sie die Übersichtlichkeit von SQL-Code erhöhen kann.&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-7009565015101319375?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/7009565015101319375/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2011/08/ssas-und-subquery-factoring.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/7009565015101319375'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/7009565015101319375'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2011/08/ssas-und-subquery-factoring.html' title='SSAS und Subquery Factoring'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-6120009784726740338</id><published>2011-08-12T05:52:00.000-07:00</published><updated>2011-08-19T04:11:29.302-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Trace'/><title type='text'>SQL Monitoring und Plan-Längen</title><content type='html'>&lt;a href="http://oracledoug.com/serendipity/index.php?/archives/1642-Real-Time-SQL-Monitoring-Statement-Not-Appearing.html"&gt;Doug Burns&lt;/a&gt; weist darauf hin, dass es ein Limit für die maximale Länge von Plänen gibt, die über dbms_sqltune.report_sql_monitor dargestellt werden können. Das Limit lässt sich über den Parameter _sqlmon_max_planlines steuern (wobei die üblichen Warnungen für das Spielen mit undokumentierten Parametern gelten).&lt;br /&gt;&lt;br /&gt;Nachtrag 19.08.2011: offenbar gibt es &lt;a href="http://oracledoug.com/serendipity/index.php?/archives/1646-Real-Time-SQL-Monitoring-Retention.html"&gt;einen weiteren Parameter _sqlmon_max_plans&lt;/a&gt;, der die Anzahl von Plänen beschränkt, die für den SQL Monitor verfügbar sind.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-6120009784726740338?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/6120009784726740338/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2011/08/sql-monitoring-und-plan-langen.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/6120009784726740338'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/6120009784726740338'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2011/08/sql-monitoring-und-plan-langen.html' title='SQL Monitoring und Plan-Längen'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-17143762.post-5614963184027331806</id><published>2011-08-12T04:31:00.000-07:00</published><updated>2011-08-12T04:32:16.910-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SQL Server'/><title type='text'>Neue Features im SQL Server Denali</title><content type='html'>Und noch mal zu Denali: &lt;a href="http://denglishbi.wordpress.com/2011/07/19/top-10-bi-reasons-to-upgrade-to-sql-server-denali-sql11/"&gt;Dan English&lt;/a&gt; führt in seinem Blog 10 Gründe für das Upgrade auf die neue SQL Server Version auf. Auf Position 1 erscheint dabei die neue Reporting-Komponente &lt;i&gt;Crescent&lt;/i&gt; und auf Platz 2 die Integration der &lt;i&gt;Vertipaq Engine&lt;/i&gt; aus PowerPivot in den SSAS. Dort wird er als &lt;i&gt;tablular model &lt;/i&gt;neben das traditionelle &lt;i&gt;multidimensional model&lt;/i&gt; gestellt. Über die Performance der neuen Engine hat Teo Latchev mehrere Artikel geschrieben und kommt dabei zum Ergebnis, dass sie nicht notwendigerweise performanter ist als das herkömmliche Verfahren:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://prologika.com/CS/blogs/blog/archive/2011/07/27/cube-vs-vertipaq-query-performance.aspx"&gt;Cube vs. VertiPaq Query Performance &lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://prologika.com/CS/blogs/blog/archive/2011/08/07/transactional-reporting-and-bism-tabular.aspx"&gt;Transactional Reporting with BISM Tabular &lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/17143762-5614963184027331806?l=martinpreiss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://martinpreiss.blogspot.com/feeds/5614963184027331806/comments/default' title='Kommentare zum Post'/><link rel='replies' type='text/html' href='http://martinpreiss.blogspot.com/2011/08/neue-features-im-sql-server-denali.html#comment-form' title='0 Kommentare'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/5614963184027331806'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/17143762/posts/default/5614963184027331806'/><link rel='alternate' type='text/html' href='http://martinpreiss.blogspot.com/2011/08/neue-features-im-sql-server-denali.html' title='Neue Features im SQL Server Denali'/><author><name>Martin Preiss</name><uri>http://www.blogger.com/profile/06388592214305009761</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='29' height='32' src='http://1.bp.blogspot.com/-LEox1RIpC6A/TiB1cr8YlkI/AAAAAAAAAWE/8Jl0Hrspfyk/s220/MP3.png'/></author><thr:total>0</thr:total></entry></feed>
