Highload++ Siberia 2019 jalanjäljissä - 8 tehtävää Oraclessa

Hi!

Novosibirskissä pidettiin 24.-25. Highload++ Siberia 2019. Myös kaverimme olivat paikalla. raportti "Oraclen konttitietokannat (CDB/PDB) ja niiden käytännön käyttö ohjelmistokehitykseen", julkaisemme tekstiversion hieman myöhemmin. Oli siistiä, kiitos olegbuniini järjestölle sekä kaikille paikalle saapuneille.

Highload++ Siberia 2019 jalanjäljissä - 8 tehtävää Oraclessa
Tässä viestissä haluamme jakaa kanssasi osastollamme esiintyneet ongelmat, jotta voit testata Oracle-tietosi. Leikkauksen alla on 8 tehtävää, vastausvaihtoehdot ja selitys.

Mikä on suurin sekvenssiarvo, jonka näemme seuraavan skriptin suorittamisen seurauksena?

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
  • Ei, tulee virhe

VastataOraclen dokumentaation mukaan (lainattu kohdasta 8.1.6):
Yhden SQL-käskyn sisällä Oracle lisää sarjaa vain kerran riviä kohden. Jos käsky sisältää useamman kuin yhden viittauksen sekvenssiin NEXTVAL, Oracle lisää sekvenssiä kerran ja palauttaa saman arvon kaikille NEXTVALin esiintymille. Jos käsky sisältää viittauksia sekä CURRVAL- että NEXTVAL-arvoon, Oracle lisää sekvenssiä ja palauttaa saman arvon sekä CURRVAL- että NEXTVAL-arvoille riippumatta niiden järjestyksestä käskyssä.

Näin ollen suurin arvo vastaa rivien määrää, eli 5.

Kuinka monta riviä taulukossa on seuraavan skriptin suorittamisen seurauksena?

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

VastataOraclen dokumentaation mukaan (lainattu kohdasta 11.2):

Ennen minkään SQL-käskyn suorittamista Oracle merkitsee implisiittisen tallennuspisteen (ei käytettävissäsi). Sitten, jos käsky epäonnistuu, Oracle palauttaa sen automaattisesti ja palauttaa sovellettavan virhekoodin SQLCA:n SQLCODE-koodiin. Jos esimerkiksi INSERT-käsky aiheuttaa virheen yrittäessään lisätä kaksoisarvon yksilölliseen indeksiin, käsky peruutetaan.

Myös asiakkaan HP:lle soittaminen katsotaan ja käsitellään yhtenä lausumana. Näin ollen ensimmäinen HP-puhelu päättyy onnistuneesti kolmen tietueen lisäämisen jälkeen; toinen HP-puhelu päättyy virheeseen ja peruuttaa neljännen tietueen, jonka se onnistui lisäämään; kolmas puhelu epäonnistuu, ja taulukossa on kolme tietuetta.

Kuinka monta riviä taulukossa on seuraavan skriptin suorittamisen seurauksena?

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

VastataOraclen dokumentaation mukaan (lainattu kohdasta 11.2):

Tarkistusrajoituksella voit määrittää ehdon, joka taulukon jokaisen rivin on täytettävä. Rajoituksen täyttämiseksi jokaisen taulukon rivin on tehtävä ehdosta joko TOSI tai tuntematon (nolla-arvon takia). Kun Oracle arvioi tietyn rivin tarkistusrajoiteehdon, ehdon kaikki sarakkeiden nimet viittaavat kyseisen rivin sarakearvoihin.

Näin ollen arvo null läpäisee tarkistuksen ja anonyymi lohko suoritetaan onnistuneesti, kunnes yritetään lisätä arvo 3. Tämän jälkeen virheenkäsittelylohko tyhjentää poikkeuksen, palautusta ei tapahdu ja taulukossa on neljä riviä jäljellä arvoilla 1, null, 2 ja uudelleen null.

Mitkä arvoparit vievät saman verran tilaa lohkossa?

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 ja X
  • B ja Y
  • C ja K
  • C ja Z
  • K ja Z
  • Minä ja J
  • J ja X
  • Kaikki luetellut

VastataTässä on otteita dokumentaatiosta (12.1.0.2) erityyppisten tietojen tallentamisesta Oraclessa.

CHAR-tietotyyppi
CHAR-tietotyyppi määrittää kiinteän pituisen merkkijonon tietokannan merkistössä. Määrität tietokannan merkistön luodessasi tietokantaa. Oracle varmistaa, että kaikilla CHAR-sarakkeeseen tallennetuilla arvoilla on valitun pituuden semantiikassa koon määrittämä pituus. Jos lisäät arvon, joka on lyhyempi kuin sarakkeen pituus, Oracle tyhjentää arvon sarakkeen pituudeksi.

VARCHAR2-tietotyyppi
VARCHAR2-tietotyyppi määrittää muuttuvan pituisen merkkijonon tietokannan merkistössä. Määrität tietokannan merkistön luodessasi tietokantaa. Oracle tallentaa merkin arvon VARCHAR2-sarakkeeseen täsmälleen määrittämäsi mukaisesti ilman tyhjiä täyttöjä, jos arvo ei ylitä sarakkeen pituutta.

NUMBER Tietotyyppi
NUMBER-tietotyyppi tallentaa nollan sekä positiiviset ja negatiiviset kiinteät luvut, joiden absoluuttiset arvot ovat 1.0 x 10-130 arvoon 1.0 x 10126, mutta eivät sisällä. Jos määrität aritmeettisen lausekkeen, jonka arvo on suurempi tai yhtä suuri kuin 1.0 x 10126, Oracle palauttaa virheen. Jokainen NUMBER-arvo vaatii 1–22 tavua. Kun tämä otetaan huomioon, sarakkeen koko tavuina tietylle numeeriselle data-arvolle NUMBER(p), jossa p on tietyn arvon tarkkuus, voidaan laskea seuraavalla kaavalla: PYÖRSYS((pituus(p)+s)/2))+1 jossa s on nolla, jos luku on positiivinen, ja s on 1, jos luku on negatiivinen.

Otetaan lisäksi ote nolla-arvojen tallentamisesta dokumentaatiosta.

Nolla on arvon puuttuminen sarakkeesta. Nollat ​​osoittavat puuttuvia, tuntemattomia tai soveltumattomia tietoja. Nollat ​​tallennetaan tietokantaan, jos ne ovat tietoarvoja sisältävien sarakkeiden välissä. Näissä tapauksissa ne vaativat 1 tavun tallentaakseen sarakkeen pituuden (nolla). Rivin lopussa olevat nollakohdat eivät vaadi tallennustilaa, koska uusi riviotsikko ilmaisee, että edellisen rivin muut sarakkeet ovat tyhjiä. Jos esimerkiksi taulukon kolme viimeistä saraketta ovat tyhjiä, näille sarakkeille ei tallenneta tietoja.

Näiden tietojen perusteella rakennamme päättelyä. Oletetaan, että tietokanta käyttää AL32UTF8-koodausta. Tässä koodauksessa venäläiset kirjaimet vievät 2 tavua.

1) A ja X, kentän a arvo 'Y' vie 1 tavun, kentän x arvo 'D' vie 2 tavua
2) B ja Y, 'Vasya' in b arvo täytetään välilyönneillä enintään 10 merkkiä ja kestää 14 tavua, 'Vasya' in d vie 8 tavua.
3) C ja K. Molempien kenttien arvo on NULL, niiden jälkeen on merkitseviä kenttiä, joten ne vievät 1 tavun.
4) C ja Z. Molempien kenttien arvo on NULL, mutta kenttä Z on taulukon viimeinen, joten se ei vie tilaa (0 tavua). Kenttä C vie 1 tavun.
5) K ja Z. Sama kuin edellisessä tapauksessa. K-kentän arvo vie 1 tavun, Z - 0.
6) I ja J. Dokumentaation mukaan molemmat arvot vievät 2 tavua. Laskemme pituuden dokumentaation kaavalla: pyöreä( (1 + 0)/2) +1 = 1 + 1 = 2.
7) J ja X. J-kentän arvo on 2 tavua, X-kentän arvo 2 tavua.

Yhteensä oikeat vaihtoehdot ovat: C ja K, I ja J, J ja X.

Mikä suunnilleen on T_I-indeksin klusterointitekijä?

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

  • Noin kymmeniä
  • Noin satoja
  • Noin tuhansia
  • Noin kymmeniä tuhansia

VastataOraclen dokumentaation mukaan (lainattu kohdasta 12.1):

B-puuindeksissä indeksin klusterointikerroin mittaa rivien fyysistä ryhmittelyä suhteessa indeksiarvoon.

Indeksien klusterointitekijä auttaa optimoijaa päättämään, onko indeksitarkistus vai koko taulukon tarkistus tehokkaampi tietyille kyselyille). Matala klusterointikerroin osoittaa tehokkaan indeksiskannauksen.

Klusterointitekijä, joka on lähellä taulukon lohkojen määrää, osoittaa, että rivit on fyysisesti järjestetty taulukkolohkoissa indeksiavaimen mukaan. Jos tietokanta suorittaa täyden taulukon tarkistuksen, tietokanta pyrkii hakemaan rivit sellaisina kuin ne on tallennettu levylle indeksiavaimen mukaan lajiteltuina. Klusterointitekijä, joka on lähellä rivien määrää, osoittaa, että rivit ovat hajallaan satunnaisesti tietokantalohkoissa suhteessa indeksiavaimeen. Jos tietokanta suorittaa täyden taulukon tarkistuksen, tietokanta ei hae rivejä missään lajiteltuun järjestykseen tämän indeksiavaimen mukaan.

Tässä tapauksessa tiedot lajitellaan ihanteellisesti, joten klusterointikerroin on yhtä suuri tai lähellä taulukon varattujen lohkojen määrää. Normaalilla 8 kilotavun lohkokoolla voit olettaa, että noin tuhat kapeaa lukuarvoa mahtuu yhteen lohkoon, joten lohkojen lukumäärä ja sen seurauksena klusterointikerroin noin kymmeniä.

Millä arvoilla N seuraava komentosarja suoritetaan onnistuneesti tavallisessa tietokannassa vakioasetuksilla?

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

VastataOraclen dokumentaation mukaan (lainattu kohdasta 11.2):

Loogiset tietokannan rajat

erä
Rajan tyyppi
Raja-arvo

Indexes
Indeksoidun sarakkeen kokonaiskoko
75 % tietokantalohkon koosta vähennettynä ylimääräisillä kuluilla

Siksi indeksoitujen sarakkeiden kokonaiskoko ei saa ylittää 6 kt. Mitä seuraavaksi tapahtuu, riippuu valitusta peruskoodauksesta. AL32UTF8-koodauksessa yksi merkki voi viedä enintään 4 tavua, joten pahimmassa tapauksessa noin 6 merkkiä mahtuu 1500 kilotavuun. Siksi Oracle estää indeksin luomisen arvolla N = 400 (kun pahimman tapauksen avaimen pituus on 1600 merkkiä * 4 tavua + rivipituus), kun taas N = 200 (tai vähemmän) indeksin luominen toimii ilman ongelmia.

INSERT-operaattori, jossa on APPEND-vihje, on suunniteltu lataamaan tietoja suorassa tilassa. Mitä tapahtuu, jos sitä sovelletaan pöytään, jossa liipaisin roikkuu?

  • Tiedot ladataan suorassa tilassa, laukaisin toimii odotetulla tavalla
  • Tiedot ladataan suorassa tilassa, mutta laukaisua ei suoriteta
  • Tiedot ladataan perinteisessä tilassa, liipaisin toimii kuten pitää
  • Tiedot ladataan perinteisessä tilassa, mutta laukaisua ei suoriteta
  • Tietoja ei ladata, virhe tallennetaan

VastataPohjimmiltaan tämä on enemmänkin logiikkakysymys. Oikean vastauksen löytämiseksi ehdotan seuraavaa päättelymallia:

  1. Lisäys suorassa tilassa suoritetaan muodostamalla tietolohko suoraan, ohittaen SQL-moottorin, mikä varmistaa suuren nopeuden. Siten liipaisimen suorittamisen varmistaminen on erittäin vaikeaa, ellei mahdotonta, eikä tässä ole mitään järkeä, koska se silti hidastaa lisäämistä radikaalisti.
  2. Liipaisimen suorittamatta jättäminen johtaa siihen, että jos taulukon tiedot ovat samat, tietokannan tila kokonaisuudessaan (muut taulukot) riippuu tilasta, jossa nämä tiedot on lisätty. Tämä tietysti tuhoaa tietojen eheyden, eikä sitä voida käyttää ratkaisuna tuotannossa.
  3. Pyydettyjen toimintojen suorittamatta jättäminen katsotaan yleensä virheeksi. Mutta tässä on syytä muistaa, että APPEND on vihje, ja vihjeiden yleinen logiikka on, että ne otetaan huomioon, jos mahdollista, mutta jos ei, niin operaattori suoritetaan ottamatta huomioon vihjettä.

Joten odotettu vastaus on tiedot ladataan normaalissa (SQL) tilassa, laukaisu käynnistyy.

Oraclen dokumentaation mukaan (lainattu kohdasta 8.04):

Rajoitusten rikkominen saa käskyn suoritettua sarjamuotoisesti käyttämällä perinteistä lisäyspolkua ilman varoituksia tai virheilmoituksia. Poikkeuksena on rajoitus, joka koskee lausekkeiden pääsyä samaan taulukkoon useammin kuin kerran tapahtumassa, mikä voi aiheuttaa virheilmoituksia.
Jos taulukossa on esimerkiksi liipaimia tai viittauksen eheys, APPEND-vihje jätetään huomioimatta, kun yrität käyttää suoralatausta INSERT:tä (sarja- tai rinnakkaismuotoista) sekä mahdollisia PARALLEL-vihjeitä tai -lauseita.

Mitä tapahtuu, kun seuraava komentosarja suoritetaan?

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);

  • Onnistunut valmistuminen
  • Syntaksivirheestä johtuva virhe
  • Virhe: Itsenäinen tapahtuma ei kelpaa
  • Virhe, joka liittyy enimmäispuhelun sisäkkäisyyden ylittymiseen
  • Vieraan avaimen rikkomusvirhe
  • Lukkoon liittyvä virhe

VastataTaulukko ja liipaisin on luotu melko oikein, eikä tämän toimenpiteen pitäisi johtaa ongelmiin. Myös itsenäiset tapahtumat triggerissä ovat sallittuja, muuten kirjaaminen ei esimerkiksi olisi mahdollista.

Ensimmäisen rivin lisäämisen jälkeen onnistunut liipaisimen käynnistys aiheuttaisi toisen rivin lisäämisen, jolloin liipaisin käynnistyisi uudelleen, lisäisi kolmannen rivin ja niin edelleen, kunnes käsky epäonnistui puheluiden enimmäissisäkkäisyyden ylittymisen vuoksi. Toinen hieno seikka tulee kuitenkin peliin. Kun liipaisin suoritetaan, ensimmäisen lisätyn tietueen vahvistusta ei ole vielä suoritettu. Siksi itsenäisessä tapahtumassa suoritettava liipaisin yrittää lisätä taulukkoon rivin, joka viittaa vieraaseen avaimeen tietueeseen, jota ei ole vielä vahvistettu. Tämä johtaa odotukseen (autonominen tapahtuma odottaa päätapahtuman sitoutumista nähdäkseen, voiko se lisätä tietoja) ja samaan aikaan päätapahtuma odottaa, että autonominen tapahtuma jatkaa toimintaansa liipaisun jälkeen. Syntyy umpikuja ja sen seurauksena autonominen tapahtuma peruuntuu lukkoon liittyvistä syistä.

Vain rekisteröityneet käyttäjät voivat osallistua kyselyyn. Kirjaudu sisään, ole kiltti.

Oliko vaikeaa?

  • Kuten kaksi sormea, päätin heti kaiken oikein.

  • Ei oikeastaan, olin väärässä parissa kysymyksessä.

  • Ratkaisin puolet oikein.

  • Arvasin vastauksen kahdesti!

  • Kirjoitan kommentteihin

14 käyttäjää äänesti. 10 käyttäjää pidättyi äänestämästä.

Lähde: will.com

Lisää kommentti