Seminář na téma Cloud Computing od Oracle v Praze
Jeden horký tip na seminář přímo od Oracle v Praze na Chodově. Dne 3.7.2013 bude Oracle pořádat seminář na téma Cloud Computing, který je zdarma. Počet míst je omezen, takže je nutné se registrovat, zde:
http://www.oracle.com/us/dm/196708-emeafm13047780mpp019-oem-1957275.html
A chovat se slušně a odregistrovat se v případě, že nebude moci. Ať jsou tam místa pro ostatní. Je to velice podobné snídaním, které kdys (nebo snad ještě?) Oracle pořádal jako zdarma přednášky/semináře, typicky na téma databáze nebo nové produkty.
středa, 3. červenec 2013, 08:30 – 11:10,V Parku 2294/4, Praha 4
Info ze stránek Oracle:
- Podíváme se, jak vám může Cloud computing pomoci realizovat požadované cíle
v obchodní i IT strategii. - Jakým způsobem začít budovat strategii v oblasti Cloud computing služeb.
- Způsob implementace Cloud computingu s využitím architektonických a
technologických vzorů. - Co všechno vám v této oblasti může nabídnout společnost Oracle.
- Jak vám Oracle může pomoci s každým aspektem plánování, nasazení, monitorování a správy Cloud prostředí.
Uvidíme se tam a nezapomeňte se oholit a pořádně obléci – Oracle měl v recepci vždycky luxusní samičky ;)
Oracle do *.BMP (a možná dále do *.JPEG a *.MOV) (část 1)
Musím říct, že jsem několikrát ve svém životě potřeboval z DB vygenerovat nějaký report a pokaždé když došlo na potřebu grafické reprezentace, snažil jsem se tomu zuby nehty vyhnout. Jenže obrázky jsou sexy, ne? Takže můj cíl je nyní generovat obrázky z databáze. Zatím pouze obrázky a pouze *.BMP. Mě by se totiž mnohem více hodila komprimovaná videa, nicméně je třebas dekomponovat. Ostatně generování *.BMP bude mít jednu krásnou vlastnost – bude možné vidět případný sub-výsledek až bych třebas psal JPEG komprimaci v PL/SQL. Mnohem rychlejší by bylo napsat to v Javě a javu si provolat či jí přímo loadnout do Oracle – funkční, rychlé, efektivní – ale nudné.
Vím o jednom problému, který mi čeká a o kterém ještě nemám úplnou představu jak ho řešit – je třeba do obrázku mimo kreslení psát, což znamená mít představu jako takové písmeno (“A”) bude v bitmapě vypadat a zatímco v Javě to stačí drawStringnout na Canvas (či Canvas2d) tady to bude vyžadovat mnohem více. Což třebas povede na nějaké čtení fontů(?) a loadování do DB a o to to bude zajímavějšejší, inu, uvidíme.
Takže hurá do hébičkování !
Bitmapa (jako BMP) vypadá jako soubor pixelů a nic víc. Nicméně i tak má BMP soubor nějakou hlavičku, kterou je třebas zapsat: Při čtení článku na wiki jsem dokonce zjistil, že BMP umožňuje Huffamanovo kódování a tedy bezztrátovou komprimaci v jisté omezené podobě, což jsem do dneška netušil.
http://en.wikipedia.org/wiki/File:BMPfileFormat.png
Což znamená, že bílý jednopixelový (1×1) obrázek nejsou 3 bajty (24 bitů – 8×3 barvy), ale 58 bajtů:
![]()
Pro pochopení jsem si vyzkoušel nějakou úpravu (modře) – konkrétně jsem z 01 přepsal pixely na 02 (2x 2x) a přidal 12 bajtů:
![]()
Fajn, to by zafungovalo, takže společně s obrázkem z wikipedie už je asi pomalu možné nějaké BMP začít tvořit. Nejprve nastřelení nějakého minimálního kódu, že je to správný směr:
1) Založení adresáře, kam se budou cpát BMP soubory:
CREATE DIRECTORY output_bmp AS 'F:\bmp_output';
2) Úplně minimální kód na zkoušku:
declare
bmp_file utl_file.file_type;
un_used_1 RAW(4):=hextoraw('42')||hextoraw('4d');
begin
bmp_file:=utl_file.fopen('OUTPUT_BMP','test.bmp','wb');
utl_file.put_raw(bmp_file,un_used_1,true);
if utl_file.is_open(bmp_file) then
utl_file.fclose_all;
end if;
end;
Je to opravdu minimální kód, který do souboru test.bmp zapíše pouze 42 a 4D (hex), což odpovídá ascii textu ‘BM‘ a je to první část hlavičky bitmapového souboru. Což v hexaeditoru (použivám WinHex 17.0 a vřele doporučuji – umí přímý zápis na disk i do RAM), vypadá takto:

Fajn, to by bylo a nyní minimální kód, pro vygenerování nejjednoduššího BMP – hlavičku, jsem sprostě opráskl z wikipedie:
declare
/* uvodni BMP hlavička BMP */
static_magic_header RAW(2):=hextoraw('42')||hextoraw('4d');
/* velikost obrázku v B */
variable_image_size RAW(4):=hextoraw('46')||hextoraw('00')||hextoraw('00')||hextoraw('00');
/* aplication specific - takze se podepišu AZOR - AZ */
static_aplication_1 RAW(2):=hextoraw('41')||hextoraw('5A');
/* aplication specific - takze se podepišu AZOR - OR */
static_aplication_2 RAW(2):=hextoraw('4F')||hextoraw('52');
/* kde končí hlavička */
static_head_end RAW(4):=hextoraw('36')||hextoraw('00')||hextoraw('00')||hextoraw('00');
/* délka DIB hlavičky */
static_dib_size RAW(4):=hextoraw('28')||hextoraw('00')||hextoraw('00')||hextoraw('00');
/* sířka obrázku */
variable_image_width RAW(4):=hextoraw('02')||hextoraw('00')||hextoraw('00')||hextoraw('00');
/* výška obrázku */
variable_image_height RAW(4):=hextoraw('02')||hextoraw('00')||hextoraw('00')||hextoraw('00');
/* počet planes */
static_image_planes RAW(2):=hextoraw('01')||hextoraw('00');
/* počet barev - 24 bitová paleta */
static_image_bits RAW(2):=hextoraw('18')||hextoraw('00');
/* bi_rgb */
static_bi_rgb RAW(4):=hextoraw('00')||hextoraw('00')||hextoraw('00')||hextoraw('00');
/* velikost pixel array (dat) - a BEZ KOMPRSE*/
variable_raw_size RAW(4):=hextoraw('10')||hextoraw('00')||hextoraw('00')||hextoraw('00');
/* pixels/metters - horizontalne i vertikalne pouziju jednu promennou */
static_pix_metter RAW(4):=hextoraw('13')||hextoraw('0B')||hextoraw('00')||hextoraw('00');
/* nezbytné barvy - nulla */
static_colors RAW(4):=hextoraw('00')||hextoraw('00')||hextoraw('00')||hextoraw('00');
/* A KONEČNĚ JEDNOTLIVÉ PIXELY (prvně však separátor) */
static_pix_separator RAW(2):= hextoraw('00')||hextoraw('00');
data_pix_1_1 RAW(3):=hextoraw('00')||hextoraw('FF')||hextoraw('FF');
data_pix_1_2 RAW(3):=hextoraw('00')||hextoraw('00')||hextoraw('FF');
data_pix_2_1 RAW(3):=hextoraw('FF')||hextoraw('00')||hextoraw('FF');
data_pix_2_2 RAW(3):=hextoraw('FF')||hextoraw('00')||hextoraw('FF');
bmp_file utl_file.file_type;
begin
bmp_file:=utl_file.fopen('OUTPUT_BMP','test_2.bmp','wb');
/* postupné zapisování všech hlaviček */
utl_file.put_raw(bmp_file,static_magic_header,true);
utl_file.put_raw(bmp_file,variable_image_size,true);
utl_file.put_raw(bmp_file,static_aplication_1,true);
utl_file.put_raw(bmp_file,static_aplication_2,true);
utl_file.put_raw(bmp_file,static_head_end,true);
utl_file.put_raw(bmp_file,static_dib_size,true);
utl_file.put_raw(bmp_file,variable_image_width,true); -- šířka
utl_file.put_raw(bmp_file,variable_image_height,true); -- výška
utl_file.put_raw(bmp_file,static_image_planes,true);
utl_file.put_raw(bmp_file,static_image_bits,true);
utl_file.put_raw(bmp_file,static_bi_rgb,true);
utl_file.put_raw(bmp_file,variable_raw_size,true);
utl_file.put_raw(bmp_file,static_pix_metter,true);
utl_file.put_raw(bmp_file,static_pix_metter,true);
utl_file.put_raw(bmp_file,static_colors,true);
utl_file.put_raw(bmp_file,static_colors,true);
/* a konečně data */
utl_file.put_raw(bmp_file,data_pix_1_1,true);
utl_file.put_raw(bmp_file,data_pix_1_2,true);
/* separátor řádku */
utl_file.put_raw(bmp_file,static_pix_separator,true);
/* druhý řádek */
utl_file.put_raw(bmp_file,data_pix_2_1,true);
utl_file.put_raw(bmp_file,data_pix_2_2,true);
/* ukončení souboru */
utl_file.put_raw(bmp_file,static_pix_separator,true);
/* a zavřít soubor */
if utl_file.is_open(bmp_file) then
utl_file.fclose_all;
end if;
end;
A wohoho – 4pixelový výsledek uložený v souboru test_2.bmp vypadá po zvětšení takto :

Vygenerované BMP
Bohužel jsem změnil bezhlavě barvu a vypadla z toho růžová :/, zrovna taková hloupá barva. Kód rozhodně není hezký a v nějakém dalším díle ho upravím. Zatím jsem vytipoval části hlaviček, které nebudu měnit (prefix static_) a ty které se s velikostí obrázku budou muset měnit a přepočítávat (prefix variable_). Vygenerovaný obrázek vypadá pak v hexaeditoru:

První BMP v Oracle zobrazená v WinHex
Tak a to by bylo pro tento díl všechno ;) V druhém to navrhuji vykrášlit a udělat nějakou funkci, která mi z BLOBu vrátí přímo hlavičku. A taky funkci, která vygeneruje prázdný obrázek. Ještě s tím bude spousta legrace.
Statistika segmentů – V$SEGMENT_STATISTICS
Dnes tip na jedno úžasné view o kterém zrovna dlouho nevím – V$SEGMENT_STATISTICS. Obecně v Oracle platí, že v tabulkách a pohledech lze nalézt téměř vše s menšíma výjimkami - například binding proměnnou v projection selectu jinak než trace eventem nedohledáme (na rozdíl od binding proměnných v predikátech), což nám třeba kdysi vadilo na Siebelu, kdy tagoval sql, které pral do databáze select xx ,’zde’ from yyy; Ale zpět k pohledu V$SEGMENT_STATISTICS, jak název napovídá je tam statistika segmentů.
Dokuementace: http://docs.oracle.com/cd/E11882_01/server.112/e10820/dynviews_3003.htm
Takže nějaká ukázka:
create table segment_test as
select rpad('A'||ROWNUM||'A',500,ROWNUM) as col from dual connect by level<1000;
A rovnou pohled V$SEGMENT_STATISTICS:

V$SEGMENT_STATISTICS
A nyní spočet statistik, jak naše tabulka vypadá (ok, jsem hulvát, ale dbms_stats.gather_table.. je strašně dlouhé ;)
analyze table SEGMENT_TEST compute statistics;
A při pohledu do all_tables je vidět, že tabulka má 72 datových bloků, což dává smysl. To jsou statistiky, které vznikly při CTASu. Takže proč to nezkusit znovu:
sqlplus / as sysdba
shutdown immediate;
startup;
Nyní V$SEGMENT_STATISTICS pro novou tabulku nevrací nic (ani prázdné řádky s nulou). Takže znovu s tím nejjednodušším:
select * from segment_test where rowid='AAATAAAABAAAVFSAAF';
A nyní pohled v V$SEGMENT_STATISTICS:

V$SEGMENT_STATISTICS - po selectu přes ROWID
Jeden přístup do segmentu, jedno čtení po selectu s jedním rowid v podmínce. Tedy funguje !
P.S. Při pohledu na mé rowid je asi jasné, že jsem doma trošku prase, ale psst ;)
“Obarvené sql” – DBA_HIST_COLORED_SQL
Při hledání jednoho objektu v all_objects jsem narazil na mnou neznámé view DBA_HIST_COLORED_SQL. Obarvené sql? Neznal jsem a vypadalo to dost zajímavě. Takže jsem otevřel dokumentaci, abych se s view blíže seznámil a dokumentace říká: View se váže na funkci AWR a možnost reportovat nejen TOP SQL, ale také ty, které si označíme (“obarvíme”) pomocí funkce DBMS_WORKLOAD_REPOSITORY.ADD_COLORED_SQL.
Zní docela fajn, AWR sbírá jen TOP SQL a tohle je možnost jak do AWR dostat SQL, které tam mít chceme, ale není v TOP.
Takže go, hébičky go, jdem to zkusit!
Nejprve nějaký dotaz, který bude jednoduchý, tak aby nebyl v TOP SQL a bylo na něm vidět obarvení:
select max(dummy) as from dual;
Pak zjistit jeho sql_id:
select * from v$sql s where s.sql_text like '%max(dummy)%'
Což je : ’1twnyk3cacmfw’. A přidat do sledovaných sql_id pro AWR report:
begin
dbms_workload_repository.add_colored_sql('1twnyk3cacmfw');
end;
A test:

Tak to by bylo přidání mezi obarvená sql a nyní sebrat snapshot, spustit sql, sebrat snapshot a zjistit jestli je opravdu reportované.
declare
i int;
begin
i:=dbms_workload_repository.create_snapshot;
dbms_output.put_line('ID='||to_char(i));
end;
Spustit sql:
select max(dummy) as from dual;
A znovu snapshot
declare
i int;
begin
i:=dbms_workload_repository.create_snapshot;
dbms_output.put_line('ID='||to_char(i));
end;
A nyní ověření, že i sql, které není zcela určitě v TOP se objeví v AWR reportu:
select * from table(DBMS_WORKLOAD_REPOSITORY.AWR_SQL_REPORT_TEXT(
l_dbid=>848445615,
l_inst_num=>1,
l_bid=>893,
l_eid=>894,
l_sqlid=>'1twnyk3cacmfw'));
WORKLOAD REPOSITORY SQL Report
Snapshot Period Summary
DB Name DB Id Instance Inst Num Startup Time Release RAC
------------ ----------- ------------ -------- --------------- ----------- ---
ORCL8 848445615 orcl8 1 24-Kvě-13 13:17 11.2.0.1.0 NO
Snap Id Snap Time Sessions Curs/Sess
--------- ------------------- -------- ---------
Begin Snap: 893 25-Kvě-13 09:12:13 40 3.3
End Snap: 894 25-Kvě-13 09:12:41 37 3.5
Elapsed: 0.47 (mins)
DB Time: 0.02 (mins)
SQL Summary DB/Inst: ORCL8/orcl8 Snaps: 893-894
Elapsed
SQL Id Time (ms)
------------- ----------
1twnyk3cacmfw 0
Module: SQL Developer
select max(dummy) as from dual
-------------------------------------------------------------
SQL ID: 1twnyk3cacmfw DB/Inst: ORCL8/orcl8 Snaps: 893-894
-> 1st Capture and Last Capture Snap IDs
refer to Snapshot IDs witin the snapshot range
-> select max(dummy) as from dual
Plan Hash Total Elapsed 1st Capture Last Capture
# Value Time(ms) Executions Snap ID Snap ID
--- ---------------- ---------------- ------------- ------------- --------------
1 2522405774 0 1 894 894
-------------------------------------------------------------
Plan 1(PHV: 2522405774)
-----------------------
Plan Statistics DB/Inst: ORCL8/orcl8 Snaps: 893-894
-> % Total DB Time is the Elapsed Time of the SQL statement divided
into the Total Database Time multiplied by 100
Stat Name Statement Per Execution % Snap
---------------------------------------- ---------- -------------- -------
Elapsed Time (ms) 0 0.4 0.0
CPU Time (ms) 0 0.0 0.0
Executions 1 N/A N/A
Buffer Gets 3 3.0 0.1
Disk Reads 0 0.0 0.0
Parse Calls 1 1.0 0.4
Rows 1 1.0 N/A
User I/O Wait Time (ms) 0 N/A N/A
Cluster Wait Time (ms) 0 N/A N/A
Application Wait Time (ms) 0 N/A N/A
Concurrency Wait Time (ms) 0 N/A N/A
Invalidations 0 N/A N/A
Version Count 1 N/A N/A
Sharable Mem(KB) 14 N/A N/A
-------------------------------------------------------------
Execution Plan
---------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 2 (100)| |
| 1 | SORT AGGREGATE | | 1 | 2 | | |
| 2 | TABLE ACCESS FULL| DUAL | 1 | 2 | 2 (0)| 00:00:01 |
---------------------------------------------------------------------------
Takže pro případ, že je třeba reportovat sql v AWR, které jsou pro nás zajímavé, ale nejsou v TOP:
DBMS_WORKLOAD_REPOSITORY.ADD_COLORED_SQL,
Tipy jak najít pain v selectu..
Potyčky s dlouhotravajícími selecty zná asi každý. Nejdůležitější je rychle a především přesně identifikovat tu největší pain v daném selectu a začít u ní. Protože až po nalezení problémového místa může teprve přijít nějaká ta optimalizace - přepis selectu, založení indexu, ohintování atd. Takže dnes pár tipů jak zjistit, co databáze dělá na právě běžícím selectu a tedy jak identifikovat problémové místo či problémová místa.
Především je třeba správně umět chápat “cost” v exekučním plánu, řádek s největším costem totiž rozhodně nemusí být problém a typicky ani není. Proč okamžitě neobvinit řádek exekučního plánu s největším costem, když nás trápí doba běhu selectu je doufám jasné a plyne to z toho, co cost představuje. Spíš si myslím, že je třeba vysvětlit větu, proč si myslím, že tenhle to zrovna nebude. Záleží hodně na systému, v dávkových systémech, které jsem doposud potkával já tomu bylo tak, že estimátor spíše počet vrácených řádků do dalšího stupně exekučního plánu podhodnocuje než nadhodnocuje. Konkrétní číslo, které se dá vyjet jednoduchým selectem je 2,58x. Tedy je 2,58x pravděpodobnější, že Oracle počet vrácených řádků v exekučním plánu podhodnotí – pochopitelně v závislosti na systému, tohle je číslo jednoho konkrétního
Důvodů proč se asi člověk bude na batch systémech bude setkávát spíše s podhonocením se asi najde několik. Obecně je tomu tak, že máme nějakou představu o datech a sloupce jsou nějakým způsobem téměř vždy korelovány, což o proti náhodným datům a operátoru AND, kdy estimátor selectivity podmínek pronásobí opravdu spíše vede k podhodnocení. Podobně rozdělení do 4 threadu ORA_HASH(id,3) je funkce se selektivitou 25%, ale defalutní selektivita pro funkce je 1%. Jinými slovy – záleží na systému a pokud tam programátor nesedí prvně, měl by mít nějakou představu -já by default očekávám, že další stupně exekučního plánu budou mít jako vstup počet řádků podhodnocen a tedy i cost bude menší než ve skutečnosti – a to nejspíše budou ty řádky, které budou trápit ;) Podhodnocení počtu očekávaných řádků vede logicky k použití indexu, tam kde to není úplně nejlepšejší..
A nyní tipy jak sledovat, co se tam děje:
1) Pohled v$session_longops
select * from v$session_longops where sid=&mysid order by start_time desc;
Velice známé view, která použije semtam nějaké IDE na zobrazení progressu či programátor. Zde je důležité správně hodnoty intepretovat. Především do view nejdou všechny operace, ale jen některé (dynamic sampling, spočet statistik, přístupy k objektům (Index/Table (Fast/Skip/)(Range/Full) Scany), Sorty, Hash join a pár dalších) Další věc – do view jdou operace trvající déle než 6 sekund – to znamená, že pokud Index Range Scan operace trvá v Nested loopě několik hodin, ovšem pro každou interaci se to vejde pod 6s tak v$session_longops nezobrazí nic ačkoliv dlouhotrvající Index Range Scan do tohoto view jde. Pozor na špatnou intepretaci těch nejzajímavějších sloupců sofar a totalwork (a jejich časové analogie). Protože výraz to_char(round((sofar/totalwork)*100)) ||’ %’ vypadá, že by mohl ukazovat kolik % již je hotovo. Ukazuje, ale ne však vždy – například pokud je tabulka partišnovaná a select je jen z jedné partition, pak totalwork ukazuje počet datových bloků pro selectovanou partition v případě, že je známá v době optimalizace (static partition prunning, where x=’X'). Pokud je konkrétní partiton známá až za běhu selectu (dynamic partition pruning, where x=(select dummy from dual)) pak totalwork je průměrný počet datových bloků všech partition tabulky). Jinými slovy do totalwork mohou vstupovat statistická data, průměry i odhady, na což je třebas myslet, když je v v$session_longops řádek hotový na 178% a stále to pokračuje ;)
A těch příkladů by se našlo více, dalším jsou například dvě a více analytické funkce v projection ukazující se v exeukčním plánu stále jako jeden řádek. Sice to vypadá jako, že to trvá jeden krok (sort operace), ale v totalwork je vidět, že počet řazených bloku s každou analytickou funkcí, může růst (až dvojnásobek, podle sloupců order by) a tedy ne, neni to zadarmo ;)
Suma sumárum: jednoduché view ve kterém toho moc není a kde je třeba umět správně intepretovat hodnoty. Co je fajn, je možnost vlastního záznamu v v$session_longops pomocí API v dbms_application_info. Další fajn věcička je, že se tam propisují í některé dlouhotrvající tooly Oracle (backupy, přepočet statistik)
2) Pohled v$active_session_history
Tohle view je mým favoritem. View jako takové neslouží ke sledování vytížení ani běhu sql, ale obsahuje snpashoty v$session po 1 vteřině včetně toho, co zrovna daná session dělá. Stačí tedy řádky zgrupovat podle sql_plan_line_id a count(*) řádků ukazuje kolik sekund na daném řádku session trávila či ještě tráví:
select count(*),his.sql_plan_line_id, his.sql_plan_operation,his.sql_plan_options from v$active_session_history his where his.SQL_ID='sql id' and sample_time>sysdate-1 group by his.sql_plan_line_id,his.sql_plan_operation,his.sql_plan_options;
Suma sumárum: Jednoduché, krásné, efektivní. Ve většině případů dostačující. Ne moc vhodné pro sledování paralelních selectů. V$active_session_history rocks!
3) Pohled v$sql_plan_monitor
V případě, že v$active_session_history je nedostatečné, je tu ještě vyšší kalibr : v$sql_plan_monitor. View do kterého jdou SQL trvající déle než 5 sekund (neni to překlep, sem po 5s do longops 6s, dle Oracle), paralelní selecty a selecty s hintem /*+ MONITOR */. A nejdou všechny ostatní – neparalelní kratší než 5s a případně s inverzním hintem /*+ NO_MONITOR */.
select * from v$sql_plan_monitor where sql_id=‘sql_id’;
V tomhle view je vidět téměř vše co je potřeba - doba potřebná pro danou operaci, jak jdou operace za sebou, jak velké byly zprávy které si mezi sebou posílaly paralelní části, počet řádků vystupujících z daného kroku, potřebná paměť, velikost tempu pro danou operaci, počet iterací nested loopy atd.
Suma sumárum: V některých případech hůře čitelné než v$active_session_history, ale lépe se tam odhalují vnořené nested loopy a je to podstatně vhodnější pro sledování paralelních selectů. Velká nevýhoda je doba po kterou v tomto view selecty zůstávají (velice krátce – desítky minut). Nejlepšejší vychytávka: Možnost zjisti v jaké nested loop iteraci zrovna Oracle je.
4) Pohled v$sesstat
Úžasné view se spoustou statistik (pro všechny session). Dokonce tolik statistik, že pro sledování běžícího selectu je vhodné dělat pomocí CTAS:
create table actual_stats as select sid,s.statistic#,value,name,class from v$sesstat s join v$statname sp
on (s.statistic#=sp.statistic#)
where s.sid=143;
A po nějaké chvilce to odečíst, aby bylo vidět co se mění:
select sid,s.statistic#,value,name,class from v$sesstat s join v$statname sp
on (s.statistic#=sp.statistic#)
where s.sid=143;
minus select * from actual_stats;
Tohle je spíše doplňková informace pro odhalení případných podezření na operace, které nejsou na první pohled vidět a nebo na detailní rozpad.
Suma sumárum: O proti ostatním pohledum není samo o sobě vhodné pro identifikaci problému v selectu (neukazuje na kterém objektu, jaký exekuční plán apod.), nicméně pomůže v případech, které nejsou patrné v ostatních view. Typickým příkladem by mohl být chybějící index v cizím klíči – full table scan, který je nutný k dodžení referenční integrity v exekučním plánu vidět není,
ve statistikách se však objeví.
Tak to by bylo pro dnešek vše ;) Tipy se snad hodí.. alespoň pro některé systémy – pro OLTP se to moc nehodí ;)
Doporučená literatura: Secrets of the Oracle Database
Dnes po delší odmlce alespoň tip na jednu knihu Secrets of the Oracle Database. I když velice rád mám oficiální dokumentaci, kterou má Oracle jako jednu z nejlepších - navíc nyní vylepšovanou o videa s tutoriálama a nově i s příklady. Jediné, co trošku kazí dojem je, že když vyťukáte adresu, kde by člověk čekal dokumentaci k Oracle 12c, tak je tam nehezká hláška, že beta dokumentace není pro každého..
Ale zpět ke knize Secrets of the Oracle Database - kniha je z vydavatelství Apress, což je vydavatelství, které o Oracle (a nejen o něm) vydává odborné knihy, což je takový unikát o proti tisíci knih popisující stále dokola funkci SUM() a UNION ALL.. Apress jde jinou cestou a vydává knihy, které často napsali velikánové typu Lewis, či Kyte a typicky se celá kniha věnuje jen jednomu tématu a hodně do hloubky (CBO, Indexy apod. jsou samostatné knihy).
Secrets of the Oracle Database od Norberta Debese se věnuje tomu nejzajímavějšímu – nedokumentované, skryté a tajné funkcionality Oracle. Zkryté parametry, fixed X$ pohledy, utility typu ORADEBUG atd.

Secrets of the Oracle Database
http://www.apress.com/9781430219521
ISBN13: 978-1-4302-1952-1
Stran: 450
Rychlotip #20 – CREATE SCHEMA
Dnešní rychlotip s číslem 20 je věnován vcelku neznámému, ale o to více užitečnému, příkazu CREATE SCHEMA. Možná to má lehce matoucí název – nemá to relaci na vytvoření schéma jako takového a klasicky schéma je vytvořeno pomocí CREATE USER. Příkaz CREATE SCHEMA slouží k vytvoření několika objektů (tabulek, view a grantů) v jedné transakci. Což se typcky hodí při nějakém updatu systému/nasazení RFC – kdy je třeba nasadit více tabulek – pomocí CREATE SCHEMA je od Oracle zaručeno, že to proběhne “jako transakce” – tedy všechno nebo nic. Normálně je CREATE TABLE příkaz typu DDL, takže se při releasu může povéct založit jen nějaké tabulky a ostatní vyhodí chybu – což bohužel vykazuje nějaký effort na srovnaní nebo to všechno vydropovat, vylézt zpět na strom a spustit to celé znovu.
Tedy jednou větou – CREATE SCHEMA umí v jedné transakci založit více objektu v jedné transakci, konkrétně:
- CREATE TABLE
- CREATE VIEW
- GRANT
Podporovaných DDL je opravdu málo a navíc neexistuje inverzní operace DROP SCHEMA, ač v SQL-1999 standard tento příkaz podporuje.
Jediné omezení je na CRETE TABLE – parallel je povoleno, ale ve skutečnosti parallně tabulky v CREATE SCHEMA nejsou zakládány a běží to seriově.
CREATE SCHEMA AUTHORIZATION dot
CREATE TABLE TEST_A (A NUMBER)
CREATE TABLE TEST_B as select 1 FROM DUAL
CREATE VIEW TEST_C as select * from all_objects
GRANT SELECT ON TEST_A TO SCOTT;
Synaxe je jednoduchá CREATE SCHEMA AUTHORIZATION <user_schema> a pak seznam tabulek, view a grantu bez středníku, středník až na konci, který zavírá statement CREATE SCHEMA.
Takže po spuštění:
SQL Error: ORA-02425: nepodařilo se vytvořit tabulku
ORA-00998: tento výraz je třeba pojmenovat alternativním jménem sloupce
02425. 00000 - "create table failed"
Protože jsem jelito a hajdalák a v TEST_B selectuji jedničku z dualu a nedal jsem tam alias, nicméně alespoň důkaz, že opravdu CREATE SCHEMA funguje a nezaložila se tabulka TEST_A ani nic jiného:

Create schema - Fail
Takže po opravě:
CREATE SCHEMA AUTHORIZATION dot
CREATE TABLE TEST_A (A NUMBER)
CREATE TABLE TEST_B as select 1 as haf FROM DUAL
CREATE VIEW TEST_C as select * from all_objects
GRANT SELECT ON TEST_A TO SCOTT;
Je výstup následující:
schema AUTHORIZATION created.
A nyní test, že se všechno založilo i nagrantovalo:

Create schema- Success
Pro nasazovací scripty šikovná věcička, co?
