Warning: Declaration of Suffusion_MM_Walker::start_el(&$output, $item, $depth, $args) should be compatible with Walker_Nav_Menu::start_el(&$output, $item, $depth = 0, $args = Array, $id = 0) in /DISK2/WWW/plsql.cz/www/wp-content/themes/suffusion/library/suffusion-walkers.php on line 39
Mar 272016
 

Godiva,

tak pod dlouhé době zase nějaký post.  Ne, že bych snad něměl nápady, co sem spát, ale prostě není čas -ale i takto tu tak nějak hodlám tento rok udržovat :) Inu, dnešní téma je DEFAULT na 12c a nová featura/optimalizace Oracle, která nás tak trošku potrápila, ale ve skutečnosti je neskutečně sexy.

Kolega nedávno objevil záhadný hidden sloupec v tabulce (a tudíš jemu patří credit) a ptal se jak se tam sakra dostal. Popravdě Oracle 12c si vlastní systémové sloupce přidává docela rád a ne vždy to člověka potěší. Při takovém SWITCH PARTITIONS to nepotěší nikdy ;) Nicméně, na otázku kolegy jsem mu nabídl vysvětlení extended statistic, Oracle 12c (v defaulutu zapnuto) si pro korelované sloupce v predikátech založí virtuální sloupec a nad nim spočitá statistiky. Což se nepotvrdilo. Určit exaktně o co přesně jde z následující tabulky:

<code>  property      number not null,           /* column properties (bit flags): */
/* 0×0001 =       1 = ADT attribute column                   */
/* 0×0002 =       2 = OID column                             */
/* 0×0004 =       4 = nested table column                    */
/* 0×0008 =       8 = virtual column                         */
/* 0×0010 =      16 = nested table’s SETID$ column           */
/* 0×0020 =      32 = hidden column                          */
/* 0×0040 =      64 = primary-key based OID column           */
/* 0×0080 =     128 = column is stored in a lob              */
/* 0×0100 =     256 = system-generated column                */
/* 0×0200 =     512 = rowinfo column of typed table/view     */
/* 0×0400 =    1024 = nested table columns setid             */
/* 0×0800 =    2048 = column not insertable                  */
/* 0×1000 =    4096 = column not updatable                   */
/* 0×2000 =    8192 = column not deletable                   */
/* 0×4000 =   16384 = dropped column                         */
/* 0×8000 =   32768 = unused column – data still in row      */
/* 0×00010000 =   65536 = virtual column                         */
/* 0×00020000 =  131072 = place DESCEND operator on top          */
/* 0×00040000 =  262144 = virtual column is NLS dependent        */
/* 0×00080000 =  524288 = ref column (present as oid col)        */
/* 0×00100000 = 1048576 = hidden snapshot base table column      */
/* 0×00200000 = 2097152 = attribute column of a user-defined ref */
/* 0×00400000 = 4194304 = export hidden column,RLS on hidden col */
/* 0×00800000 = 8388608 = string column measured in characters   */
/* 0×01000000 = 16777216 = virtual column expression specified    */
/* 0×02000000 = 33554432 = typeid column                          */
/* 0×04000000 = 67108864 = Column is encrypted                    */
/* 0×20000000 = 536870912 = Column is encrypted without salt       */

/* 0×000800000000 = 34359738368 = default with sequence                */
/* 0×001000000000 = 68719476736 = default on null                      */
/* 0×002000000000 = 137438953472 = generated always identity column    */
/* 0×004000000000 = 274877906944 = generated by default identity col   */
/* 0×080000000000 = 8796093022208 = Column is sensitive                */
</code>

No dobře, neni to přesně tabulka, ale jsou to vykopírované komentáře z rdbms/admin/dcore.bsq. A obecně jsou tyto typy souboru (admin/*.bsq) vhodné pro zkoumání, co která hodnota PROPERTY asi tak znamená (pro mně novinka).

Zkrátka jsme po chvíli přišli na to, že se jednalo o přidání sloupce s DEFALUTEM na NULLABLE sloupec – zatímco v 11g si Oracle musí naupdatovat všechny řádky s novou DEFULAT hodnotou, na 12c se jedná pouze o změnu definici tabulky a běh v řádu častí sekundy – ovšem za cenu nového hidden sloupce, který nyní udržuje informaci, zda-li je v řádku reálně NULL nebo DEFAULT hodnota. Krásný článek je o tom přímo u Oracle: http://www.oracle.com/technetwork/articles/database/ddl-optimizaton-in-odb12c-2331068.html. Který navíc krásně popisuje jak to pak funguje, když se na sloupec dotazuji (použití NVL na určení, co je je opravdová hodnota).

Takže zkouška:
CREATE TABLE T_TEST(a VARCHAR2(1), b VARCHAR2(2));
INSERT INTO T_TEST VALUES ('a', 'b');
INSERT INTO T_TEST VALUES ('a', 'b');
INSERT INTO T_TEST VALUES ('a', 'b');
ALTER TABLE T_TEST ADD (c VARCHAR2(1) DEFAULT 'z');
INSERT INTO T_TEST(a,b,c) VALUES ('a', 'b',null);
INSERT INTO T_TEST(a,b,c) VALUES ('a', 'b',null);
INSERT INTO T_TEST(a,b,c) VALUES ('a', 'b',null);

A nyní pohled na data (s jedním řádkem, před přidáním constrainu):

V tabulce je nově sloupce SYS_N00003$, který určuje, jestli se jedná reálně o NULL, nebo o sloupec ve kterém byl NULL před přidáním constrainu a tudíš by nyní měl obsahovat “z”. Oracle na to musí aplikovat funkce a rozhodnout, která hodnota je tedyy platná – ve sloupci C/default či SYS_N00003$. Jak to dělá ukazuje linknutý článek na Oracle.com – co je nutné podotknout, není to vidět před spuštěním ale až v reálném exekučním plánu. Článek to ukazuje na predikátu, ale stačí kouknout do PROJECTION : DECODE(TO_CHAR(SYS_OP_VECBIT(“SYS_NC00003$”,0)),NULL,NVL(“C”,’z’),’0′,NVL(“C”,’z’),’1′,”C”). A to samé si pak mohu použít v SQL:

Jak se toho zbavit?

Expost, popravdě nevím – sloupec nelze droponout (ORA-14148) a ani s pár pokusama změnit pod system PROPERTY jsem neuspěl :(. Nicméně jedná se o novinku a obyčejně Oracle “somehow” umožňuje nové chování potlačit. Obyčejně se jedná o zkryté parametry. Což se hledá velice špatně – většinou řeším LIKE + kombinace s hodnotou o které si myslím, že je právě nastavena. Tedy zkrytý parametr obsahující slovo NULL, který je nastaven na TRUE:

select * from (
SELECT
a.ksppinm Param ,
b.ksppstvl SessionVal ,
c.ksppstvl InstanceVal,
a.ksppdesc Descr
FROM
x$ksppi a ,
x$ksppcv b ,
x$ksppsv c
WHERE
a.indx = b.indx AND
a.indx = c.indx AND
a.ksppinm LIKE '/_%' escape '/'
AND b.ksppstvl='TRUE'
ORDER BY
1)
where upper(descr) like '%NULL%'
;

S tím, že mi to našlo celkem 5 parametrů. Většina se týká joinu a pak _add_nullable_column_with_default_optim. Tento zkrytý parametr je možné nastavit i na úrovni session i na úrovni instance a neni statistký. Sice nepodporovaný, ale když si před přidáním DEFAULT hodnoty na NULLABLE sloupce vylatrujete session :

alter system set "_add_nullable_column_with_default_optim"=false;

So, nepříjemnost při SWITCHOVÁNÍ PARTITIONS či použití ALL_TAB_COLS místo ALL_TAB_COLUMNS nebo sexy věc při přidání DEFAULTu na sloupec (nyní nově na nullable sloupec) v tabulce s 100mil záznamy a během v řádu desetin sekundy ;) Podle toho, kdo jste ;)

 Posted by at 15:31

 Leave a Reply

(required)

(required)

(required)

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>