Um mir die Details besser merken zu können, spiele ich ein paar der Beispiele hier nach:
-- Setzen der system stats begin dbms_stats.set_system_stats('CPUSPEED', 500); dbms_stats.set_system_stats('SREADTIM', 5.0); dbms_stats.set_system_stats('MREADTIM', 30.0); dbms_stats.set_system_stats('MBRC', 12); end; / -- Anlage eines TS ohne ASSM CREATE TABLESPACE test_ts datafile 'C:\ORADATA\TESTDB\TEST_TS01.DBF' size 100M autoextend on maxsize unlimited EXTENT MANAGEMENT LOCAL SEGMENT SPACE MANAGEMENT MANUAL; -- Anlage einer Testtabelle + Statistikerhebung create table test tablespace test_ts as select case when rownum <= 10000 then mod(rownum, 10) else 100 end rn , lpad('*', 100, '*') pad from dual connect by level <= 1000000; exec dbms_stats.gather_table_stats (ownname=>user, tabname=>'test') -- Infos zur Tabelle SQL> exec show_space('TEST') PL/SQL-Prozedur erfolgreich abgeschlossen. Abgelaufen: 00:00:00.19 SQL> set serveroutput on SQL> exec show_space('TEST') Free Blocks............................. 0 Total Blocks............................ 15,360 Total Bytes............................. 125,829,120 Total MBytes............................ 120 Unused Blocks........................... 207 Unused Bytes............................ 1,695,744 Last Used Ext FileId.................... 5 Last Used Ext BlockId................... 14,464 Last Used Block......................... 817 PL/SQL-Prozedur erfolgreich abgeschlossen.
Nach Jonathan Lewis errechnen sich die Kosten in diesem Fall als:
(Anzahl_Blocks / MBRC) * (MREADTIM/SREADTIM)also:
SQL> select (15360/12) * (30/5) from dual; (15360/12)*(30/5) ----------------- 7680 -- Testquery SQL> select count(*) from test; Abgelaufen: 00:00:00.06 Ausf³hrungsplan -------------------------------------------------------- Plan hash value: 1950795681 -------------------------------------------------------- | Id | Operation | Name | Rows | Cost (%CPU)| -------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 7680 (2)| | 1 | SORT AGGREGATE | | 1 | | | 2 | TABLE ACCESS FULL| TEST | 1000K| 7680 (2)| --------------------------------------------------------
Das Ergebnis entspricht also genau den Erwartungen. Jetzt noch eine kleine Variante: ich setze MBRC auf 16:
exec dbms_stats.set_system_stats('MBRC', 16) SQL> select (15360/16) * (30/5) from dual; (15360/16)*(30/5) ----------------- 5760 SQL> select count(*) from test; Abgelaufen: 00:00:00.07 Ausf³hrungsplan --------------------------------------------------------- Plan hash value: 1950795681 --------------------------------------------------------- | Id | Operation | Name | Rows | Cost (%CPU)| --------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 5786 (2)| | 1 | SORT AGGREGATE | | 1 | | | 2 | TABLE ACCESS FULL| TEST | 1000K| 5786 (2)| ---------------------------------------------------------
Keine große Abweichung, aber doch eine, über die ich noch nachdenken muss.
Nachtrag 29.04.2011: Bei erneuter Untersuchung des Themas ist mir der Rechenfehler aufgefallen: ich hatte die Blocks oberhalb der HWM eingerechnet. Mit der richtigen Rechnung erhält man dann auch das passende Ergebnis: (15360-207)/16 * 30/5 = 5682,375. Das entspricht dem autotrace-Ergebnis bei Auswahl eines extremen CPU-Speeds (ein Trick, den man in Randolf Geists Artikeln zum Thema findet):
------------------------------------------------------------------- | Id | Operation | Name | Rows | Cost (%CPU)| Time | ------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 5682 (0)| 00:00:29 | | 1 | SORT AGGREGATE | | 1 | | | | 2 | TABLE ACCESS FULL| TEST | 1000K| 5682 (0)| 00:00:29 | -------------------------------------------------------------------
Keine Kommentare:
Kommentar veröffentlichen