Slijedeći korake Highload++ Siberia 2019 - 8 zadataka na Oracleu

Pozdrav!

Od 24. do 25. lipnja u Novosibirsku je održana konferencija Highload++ Siberia 2019. Bili su tamo i naši dečki izvješće “Oracle kontejnerske baze podataka (CDB/PDB) i njihova praktična primjena za razvoj softvera”, tekstualnu verziju objavit ćemo nešto kasnije. Bilo je cool, hvala olegbunin za organizaciju, kao i svima koji su došli.

Slijedeći korake Highload++ Siberia 2019 - 8 zadataka na Oracleu
U ovom postu želimo s vama podijeliti probleme koje smo imali na našem štandu kako biste mogli testirati svoje znanje o Oracleu. Ispod presjeka je 8 zadataka, mogućnosti odgovora i objašnjenje.

Koja je najveća vrijednost niza koju ćemo vidjeti kao rezultat izvršavanja sljedeće skripte?

create sequence s start with 1;
 
select s.currval, s.nextval, s.currval, s.nextval, s.currval
from dual
connect by level <= 5;

  • 1
  • 5
  • 10
  • 25
  • Ne, doći će do pogreške

OdgovoritiPrema Oracle dokumentaciji (citirano iz 8.1.6):
Unutar jedne SQL naredbe, Oracle će povećati niz samo jednom po retku. Ako izjava sadrži više od jedne reference na NEXTVAL za niz, Oracle povećava niz jednom i vraća istu vrijednost za sva pojavljivanja NEXTVAL-a. Ako izraz sadrži reference i na CURRVAL i na NEXTVAL, Oracle povećava niz i vraća istu vrijednost i za CURRVAL i za NEXTVAL bez obzira na njihov redoslijed unutar izraza.

Dakle, maksimalna vrijednost će odgovarati broju linija, to jest 5.

Koliko će redaka biti u tablici kao rezultat pokretanja sljedeće skripte?

create table t(i integer check (i < 5));
 
create procedure p(p_from integer, p_to integer) as
begin
    for i in p_from .. p_to loop
        insert into t values (i);
    end loop;
end;
/
 
exec p(1, 3);
exec p(4, 6);
exec p(7, 9);

  • 0
  • 3
  • 4
  • 5
  • 6
  • 9

OdgovoritiPrema Oracle dokumentaciji (citirano iz 11.2):

Prije izvršavanja bilo koje SQL naredbe, Oracle označava implicitnu točku spremanja (koja vam nije dostupna). Zatim, ako izraz ne uspije, Oracle ga automatski vraća natrag i vraća primjenjivi kod greške u SQLCODE u SQLCA. Na primjer, ako izraz INSERT uzrokuje pogrešku pokušajem umetanja duple vrijednosti u jedinstveni indeks, izraz se vraća natrag.

Pozivanje HP-a od klijenta također se smatra i obrađuje kao jedna izjava. Dakle, prvi HP poziv je uspješno završen, nakon umetanja tri zapisa; drugi HP poziv završava s pogreškom i vraća četvrti zapis koji je uspio umetnuti; treći poziv ne uspijeva, a u tablici su tri zapisa.

Koliko će redaka biti u tablici kao rezultat pokretanja sljedeće skripte?

create table t(i integer, constraint i_ch check (i < 3));
 
begin
    insert into t values (1);
    insert into t values (null);
    insert into t values (2);
    insert into t values (null);
    insert into t values (3);
    insert into t values (null);
    insert into t values (4);
    insert into t values (null);
    insert into t values (5);
exception
    when others then
        dbms_output.put_line('Oops!');
end;
/

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

OdgovoritiPrema Oracle dokumentaciji (citirano iz 11.2):

Ograničenje provjere omogućuje vam da odredite uvjet koji svaki red u tablici mora zadovoljiti. Da bi se zadovoljilo ograničenje, svaki redak u tablici mora učiniti uvjet TRUE ili nepoznat (zbog nule). Kada Oracle procjenjuje uvjet ograničenja provjere za određeni redak, svi nazivi stupaca u uvjetu odnose se na vrijednosti stupaca u tom retku.

Dakle, vrijednost null proći će provjeru, a anonimni blok će se uspješno izvršiti do pokušaja umetanja vrijednosti 3. Nakon toga, blok za obradu pogrešaka će ukloniti iznimku, neće doći do povratka i u tablici će ostati četiri retka s vrijednostima 1, null, 2 i opet null.

Koji parovi vrijednosti će zauzeti istu količinu prostora u bloku?

create table t (
    a char(1 char),
    b char(10 char),
    c char(100 char),
    i number(4),
    j number(14),
    k number(24),
    x varchar2(1 char),
    y varchar2(10 char),
    z varchar2(100 char));
 
insert into t (a, b, i, j, x, y)
    values ('Y', 'Вася', 10, 10, 'Д', 'Вася');

  • A i X
  • B i Y
  • C i K
  • C i Z
  • K i Z
  • ja i J
  • J i X
  • Svi navedeni

OdgovoritiOvdje su izvatci iz dokumentacije (12.1.0.2) o pohranjivanju različitih vrsta podataka u Oracle.

Vrsta podataka CHAR
Tip podataka CHAR specificira znakovni niz fiksne duljine u skupu znakova baze podataka. Skup znakova baze podataka navodite kada stvarate svoju bazu podataka. Oracle osigurava da sve vrijednosti pohranjene u stupcu CHAR imaju duljinu određenu veličinom u semantici odabrane duljine. Ako umetnete vrijednost koja je kraća od duljine stupca, tada Oracle unosi vrijednost u prazninu duljine stupca.

Vrsta podataka VARCHAR2
Tip podataka VARCHAR2 specificira znakovni niz varijabilne duljine u skupu znakova baze podataka. Skup znakova baze podataka navodite kada stvarate svoju bazu podataka. Oracle pohranjuje vrijednost znaka u stupac VARCHAR2 točno onako kako ste ga naveli, bez ikakvih praznina, pod uvjetom da vrijednost ne premašuje duljinu stupca.

Vrsta podataka NUMBER
Tip podataka BROJ pohranjuje nulu, kao i pozitivne i negativne fiksne brojeve s apsolutnim vrijednostima od 1.0 x 10-130 do, ali ne uključujući 1.0 x 10126. Ako navedete aritmetički izraz čija vrijednost ima apsolutnu vrijednost veću ili jednaku 1.0 x 10126, tada Oracle vraća pogrešku. Svaka vrijednost BROJ zahtijeva od 1 do 22 bajta. Uzimajući to u obzir, veličina stupca u bajtovima za određenu numeričku vrijednost podataka BROJ(p), gdje je p preciznost dane vrijednosti, može se izračunati pomoću sljedeće formule: OKRUGLO((duljina(p)+s)/2))+1 gdje je s jednako nuli ako je broj pozitivan, a s jednak 1 ako je broj negativan.

Uz to, uzmimo izvadak iz dokumentacije o pohranjivanju Null vrijednosti.

Null je odsutnost vrijednosti u stupcu. Null označava podatke koji nedostaju, nepoznate su ili neprimjenjive. Null vrijednosti pohranjuju se u bazu podataka ako padnu između stupaca s vrijednostima podataka. U tim slučajevima, oni zahtijevaju 1 bajt za pohranjivanje duljine stupca (nula). Završne nulte vrijednosti u retku ne zahtijevaju pohranu jer novo zaglavlje retka signalizira da su preostali stupci u prethodnom retku nulti. Na primjer, ako su posljednja tri stupca tablice nula, tada se za te stupce ne pohranjuju podaci.

Na temelju tih podataka gradimo rasuđivanje. Pretpostavljamo da baza podataka koristi AL32UTF8 kodiranje. U ovom kodiranju, ruska slova će zauzeti 2 bajta.

1) A i X, vrijednost polja a 'Y' zauzima 1 bajt, vrijednost polja x 'D' zauzima 2 bajta
2) B i Y, 'Vasya' u b vrijednost će biti dopunjena razmacima do 10 znakova i zauzimat će 14 bajtova, 'Vasya' u d će zauzimati 8 bajtova.
3) C i K. Oba polja imaju vrijednost NULL, iza njih su značajna polja, pa zauzimaju 1 bajt.
4) C i Z. Oba polja imaju vrijednost NULL, ali je polje Z posljednje u tablici, pa ne zauzima prostor (0 bajtova). Polje C zauzima 1 bajt.
5) K i Z. Slično prethodnom slučaju. Vrijednost u K polju zauzima 1 bajt, u Z – 0.
6) I i J. Prema dokumentaciji, obje vrijednosti će zauzeti 2 bajta. Duljinu izračunavamo pomoću formule preuzete iz dokumentacije: okrugli( (1 + 0)/2) +1 = 1 + 1 = 2.
7) J i X. Vrijednost u polju J zauzimat će 2 bajta, vrijednost u polju X zauzimat će 2 bajta.

Ukupno, točne opcije su: C i K, I i J, J i X.

Koliki će otprilike biti faktor grupiranja T_I indeksa?

create table t (i integer);
 
insert into t select rownum from dual connect by level <= 10000;
 
create index t_i on t(i);

  • Oko desetaka
  • Otprilike stotine
  • Oko tisuća
  • Oko desetak tisuća

OdgovoritiPrema Oracle dokumentaciji (citirano iz 12.1):

Za indeks B-stabla, faktor klasteriranja indeksa mjeri fizičko grupiranje redaka u odnosu na vrijednost indeksa.

Faktor klasteriranja indeksa pomaže optimizatoru da odluči je li skeniranje indeksa ili skeniranje cijele tablice učinkovitije za određene upite). Nizak faktor klasteriranja ukazuje na učinkovito skeniranje indeksa.

Faktor grupiranja koji je blizak broju blokova u tablici označava da su redovi fizički poredani u blokovima tablice prema ključu indeksa. Ako baza podataka izvodi potpuno skeniranje tablice, tada baza podataka nastoji dohvatiti retke dok su pohranjeni na disku sortirane prema ključu indeksa. Faktor grupiranja koji je blizak broju redaka pokazuje da su redovi nasumično razbacani po blokovima baze podataka u odnosu na ključ indeksa. Ako baza podataka izvodi potpuno skeniranje tablice, tada baza podataka neće dohvatiti retke u bilo kojem poredanom redoslijedu prema ovom ključu indeksa.

U ovom slučaju podaci su idealno sortirani, pa će faktor klasteriranja biti jednak ili blizak broju zauzetih blokova u tablici. Za standardnu ​​veličinu bloka od 8 kilobajta, možete očekivati ​​da će oko tisuću uskih brojčanih vrijednosti stati u jedan blok, tako da će broj blokova, i kao rezultat, faktor grupiranja biti oko desetaka.

Pri kojim vrijednostima N će se sljedeća skripta uspješno izvršiti u redovnoj bazi podataka sa standardnim postavkama?

create table t (
    a varchar2(N char),
    b varchar2(N char),
    c varchar2(N char),
    d varchar2(N char));
 
create index t_i on t (a, b, c, d);

  • 100
  • 200
  • 400
  • 800
  • 1600
  • 3200
  • 6400

OdgovoritiPrema Oracle dokumentaciji (citirano iz 11.2):

Ograničenja logičke baze podataka

Stavka
Vrsta ograničenja
Granična vrijednost

Indeksi
Ukupna veličina indeksiranog stupca
75% veličine bloka baze podataka minus nešto režijskih troškova

Dakle, ukupna veličina indeksiranih stupaca ne smije premašiti 6Kb. Što će se sljedeće dogoditi ovisi o odabranom osnovnom kodiranju. Za AL32UTF8 kodiranje, jedan znak može zauzeti najviše 4 bajta, tako da će u najgorem slučaju oko 6 znakova stati u 1500 kilobajta. Stoga će Oracle onemogućiti stvaranje indeksa na N = 400 (kada je duljina ključa u najgorem slučaju 1600 znakova * 4 bajta + duljina rowid), dok pri N = 200 (ili manje) stvaranje indeksa radit će bez problema.

Operator INSERT sa savjetom APPEND dizajniran je za učitavanje podataka u izravnom načinu rada. Što se događa ako se nanese na stol na kojem visi okidač?

  • Podaci će se učitati u izravnom načinu rada, okidač će raditi kako se očekuje
  • Podaci će se učitati u izravnom načinu rada, ali okidač se neće izvršiti
  • Podaci će se učitati u uobičajenom načinu rada, okidač će raditi kako treba
  • Podaci će se učitati u uobičajenom načinu rada, ali okidač se neće izvršiti
  • Podaci se neće učitati, bit će zabilježena pogreška

OdgovoritiUglavnom, ovo je više pitanje logike. Kako bih pronašao točan odgovor, predložio bih sljedeći model razmišljanja:

  1. Umetanje u izravnom načinu rada izvodi se izravnim formiranjem bloka podataka, zaobilazeći SQL mehanizam, što osigurava veliku brzinu. Dakle, osigurati izvršenje okidača je vrlo teško, ako ne i nemoguće, i nema smisla u tome, jer će i dalje radikalno usporiti umetanje.
  2. Neuspjeh u izvršenju okidača će dovesti do činjenice da će, ako su podaci u tablici isti, stanje baze podataka u cjelini (druge tablice) ovisiti o načinu na koji su ti podaci umetnuti. To će očito uništiti integritet podataka i ne može se primijeniti kao rješenje u proizvodnji.
  3. Nemogućnost izvođenja tražene operacije općenito se tretira kao pogreška. Ali ovdje se trebamo sjetiti da je APPEND hint, a opća logika hintova je da se uzimaju u obzir ako je moguće, ali ako ne, operator se izvršava bez uzimanja hinta u obzir.

Dakle, očekivani odgovor je podaci će se učitati u normalnom (SQL) načinu rada, aktivirat će se okidač.

Prema Oracle dokumentaciji (citirano iz 8.04):

Kršenja ograničenja uzrokovat će serijsko izvršavanje naredbe, korištenjem konvencionalne staze umetanja, bez upozorenja ili poruka o pogrešci. Izuzetak je ograničenje izjava koje pristupaju istoj tablici više puta u transakciji, što može uzrokovati poruke o pogrešci.
Na primjer, ako su u tablici prisutni okidači ili referentni integritet, tada će se savjet APPEND zanemariti kada pokušate koristiti INSERT izravnog učitavanja (serijski ili paralelno), kao i savjet ili klauzula PARALLEL, ako postoji.

Što će se dogoditi kada se izvrši sljedeća skripta?

create table t(i integer not null primary key, j integer references t);
 
create trigger t_a_i after insert on t for each row
declare
    pragma autonomous_transaction;
begin
    insert into t values (:new.i + 1, :new.i);
    commit;
end;
/
 
insert into t values (1, null);

  • Uspješan završetak
  • Neuspjeh zbog sintaktičke pogreške
  • Pogreška: Autonomna transakcija nije važeća
  • Pogreška povezana s prekoračenjem maksimalnog broja poziva
  • Pogreška kršenja stranog ključa
  • Pogreška povezana s bravama

OdgovoritiTablica i okidač kreirani su sasvim ispravno i ova operacija ne bi trebala dovesti do problema. Dopuštene su i autonomne transakcije u okidaču, jer u suprotnom, primjerice, evidentiranje ne bi bilo moguće.

Nakon umetanja prvog retka, uspješno aktiviranje okidača uzrokovalo bi umetanje drugog retka, uzrokujući ponovno aktiviranje okidača, umetanje trećeg retka i tako dalje sve dok izjava ne uspije zbog prekoračenja maksimalnog broja poziva. Međutim, još jedna suptilna točka dolazi u obzir. U vrijeme kada se okidač izvrši, potvrda još nije dovršena za prvi umetnuti zapis. Stoga, okidač koji se izvodi u autonomnoj transakciji pokušava u tablicu umetnuti redak koji upućuje na strani ključ na zapis koji još nije uvršten. To rezultira čekanjem (autonomna transakcija čeka da se glavna transakcija obveže da vidi može li umetnuti podatke), a u isto vrijeme glavna transakcija čeka da autonomna transakcija nastavi s radom nakon okidača. Dolazi do zastoja i, kao rezultat toga, autonomna transakcija je otkazana zbog razloga povezanih sa zaključavanjima.

U anketi mogu sudjelovati samo registrirani korisnici. Prijaviti se, molim.

Bilo je teško?

  • Kao dva prsta, odmah sam sve ispravno odlučio.

  • Ne baš, pogriješio sam na par pitanja.

  • Pola sam točno riješio.

  • Dva puta sam pogodio odgovor!

  • Napisat ću u komentarima

Glasovalo je 14 korisnika. Suzdržano je bilo 10 korisnika.

Izvor: www.habr.com

Dodajte komentar