-- Blockgröße 16 K SQL> sho parameter db_block_size NAME TYPE VALUE ------------------------------------ ----------- ----- db_block_size integer 16384 -- Anlage einer Testtabelle SQL> create table t1 2 as 3 select rownum col1 4 from dual 5 connect by level < 10000; Tabelle wurde erstellt. SQL> r 1 select blockid 2 , count(*) 3 , sum(colsize) 4 from (select dbms_rowid.rowid_block_number(rowid) blockid 5 , vsize(col1) colsize 6 from t1) 7 group by blockid 8* order by blockid BLOCKID COUNT(*) SUM(COLSIZE) ---------- ---------- ------------ 224 1327 3869 225 1327 3968 226 1327 3968 227 1327 3967 228 1327 3968 229 1327 3968 230 1327 3968 231 710 2123 8 Zeilen ausgewählt.
Die komplett gefüllten Blocks enthalten also jeweils 1327 Sätze, aber die Nettodaten der einzigen Tabellenspalte umfassen jeweils nur ca. 4K - also nur ein Viertel der Blocksize!
Eine Änderung der PCTFREE-Einstellung von 10 auf 0 verändert das Ergebnis im erwarteten Umfang von ~ 10%:
SQL> r 1 select blockid 2 , count(*) 3 , sum(colsize) 4 from (select dbms_rowid.rowid_block_number(rowid) blockid 5 , vsize(col2) colsize 6 from t2) 7 group by blockid 8* order by blockid BLOCKID COUNT(*) SUM(COLSIZE) ---------- ---------- ------------ 236 1475 4312 237 1475 4410 238 1475 4410 239 1475 4410 240 1475 4411 241 1475 4410 242 1149 3436 7 Zeilen ausgewählt.
Man kann sich den Inhalt eines Blocks ansehen, indem man einen Blockdump erstellt:
SQL> alter system dump datafile 4 block 224; System wurde geändert.
Der Dump wird im user_dump_dest abgelegt und enthält diverse Repräsentationen der Blockinhalte, darunter eine hexadezimale Darstellung, in der man die Datenverteilung relativ gut erkennen kann. Dort sieht man im gegebenen Fall auch relativ große Lücken, die ich mir aktuell noch nicht erklären kann.
Deshalb noch ein dritter Versuch mit String-Werten fester Breite:
SQL> r 1 create table t3 2 as 3 select 'AAAAAAAA' col3 4 from dual 5* connect by level < 10000 Tabelle wurde erstellt. SQL> r 1 select blockid 2 , count(*) 3 , sum(colsize) 4 from (select dbms_rowid.rowid_block_number(rowid) blockid 5 , vsize(col3) colsize 6 from t3) 7 group by blockid 8* order by blockid BLOCKID COUNT(*) SUM(COLSIZE) ---------- ---------- ------------ 248 1043 8344 249 1043 8344 250 1043 8344 251 1043 8344 252 1043 8344 253 1043 8344 254 1043 8344 255 1043 8344 256 1043 8344 257 612 4896 10 Zeilen ausgewählt.
Hier entspricht die vsize sehr genau den Erwartungen, aber die Blocks sind offenbar trotzdem nur halb gefüllt. Im Blockdump sieht man nach einem Blockheader von ca. 2000 Zeichen folgende Muster:
... 011CD8720 41414141 0801002C 41414141 41414141 [AAAA,...AAAAAAAA] 011CD8730 0801002C 41414141 41414141 0801002C [,...AAAAAAAA,...] 011CD8740 41414141 41414141 0801002C 41414141 [AAAAAAAA,...AAAA] 011CD8750 41414141 0801002C 41414141 41414141 [AAAA,...AAAAAAAA] 011CD8760 0801002C 41414141 41414141 0801002C [,...AAAAAAAA,...] 011CD8770 41414141 41414141 0801002C 41414141 [AAAAAAAA,...AAAA] 011CD8780 41414141 0801002C 41414141 41414141 [AAAA,...AAAAAAAA] 011CD8790 0801002C 41414141 41414141 0801002C [,...AAAAAAAA,...] 011CD87A0 41414141 41414141 0801002C 41414141 [AAAAAAAA,...AAAA] ...
Offenbar ist die Speicherung für die Sätze weniger kompakt und die (row) directory Informationen sind umfangreicher, als ich das angenommen hätte. (Die verlinkte Seite erklärt "The row directory uses 2 bytes per stored row.", aber sicher zuordnen kann ich diese Struktur im Blockdump nicht)
Erwartungsgemäß lassen sich wenige große Sätze besser in den Block unterbringen:
SQL> create table t4 2 as 3 select rpad('*', 1000, '*') col4 4 from dual 5 connect by level <= 32; Tabelle wurde erstellt. SQL> select blockid 2 , count(*) 3 , sum(colsize) 4 from (select dbms_rowid.rowid_block_number(rowid) blockid 5 , vsize(col4) colsize 6 from t4) 7 group by blockid 8 order by blockid; BLOCKID COUNT(*) SUM(COLSIZE) ---------- ---------- ------------ 328 14 14000 329 14 14000 330 4 4000
Für kleine Rows ist der Overhead des row directory denmach recht signifikant, für größere spielt er eine weniger wichtige Rolle.
Keine Kommentare:
Kommentar veröffentlichen