Volg in die voetspore van Highload++ Siberia 2019 - 8 take op Oracle

Привет!

Op 24-25 Junie is die Highload++ Siberia 2019-konferensie in Novosibirsk gehou. Ons ouens was ook daar rapporteer "Oracle-houerdatabasisse (CDB/PDB) en hul praktiese gebruik vir sagteware-ontwikkeling", ons sal 'n teksweergawe 'n bietjie later publiseer. Dit was gaaf, dankie olegbunien vir die organisasie, asook vir almal wat gekom het.

Volg in die voetspore van Highload++ Siberia 2019 - 8 take op Oracle
In hierdie pos wil ons graag die probleme wat ons by ons stand gehad het met jou deel sodat jy jou Oracle-kennis kan toets. Onder die snit is 8 probleme, antwoordopsies en verduideliking.

Wat is die maksimum volgordewaarde wat ons sal sien as gevolg van die uitvoering van die volgende skrif?

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
  • Nee, daar sal 'n fout wees

BeantwoordVolgens Oracle-dokumentasie (aangehaal vanaf 8.1.6):
Binne 'n enkele SQL-stelling sal Oracle die volgorde slegs een keer per ry verhoog. As 'n stelling meer as een verwysing na NEXTVAL vir 'n ry bevat, verhoog Oracle die volgorde een keer en gee dieselfde waarde terug vir alle gevalle van NEXTVAL. As 'n stelling verwysings na beide CURRVAL en NEXTVAL bevat, verhoog Oracle die volgorde en gee dieselfde waarde vir beide CURRVAL en NEXTVAL terug, ongeag hul volgorde binne die stelling.

So, die maksimum waarde sal ooreenstem met die aantal reëls, dit is 5.

Hoeveel rye sal in die tabel wees as gevolg van die loop van die volgende skrif?

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

BeantwoordVolgens Oracle-dokumentasie (aangehaal vanaf 11.2):

Voordat enige SQL-stelling uitgevoer word, merk Oracle 'n implisiete stoorpunt (nie vir jou beskikbaar nie). Dan, as die stelling misluk, rol Oracle dit outomaties terug en stuur die toepaslike foutkode terug na SQLCODE in die SQLCA. Byvoorbeeld, as 'n INSERT-stelling 'n fout veroorsaak deur te probeer om 'n duplikaatwaarde in 'n unieke indeks in te voeg, word die stelling teruggerol.

Om HP van die kliënt af te bel, word ook as 'n enkele verklaring beskou en verwerk. Dus, die eerste HP-oproep voltooi suksesvol, nadat drie rekords ingevoeg is; die tweede HP-oproep eindig met 'n fout en rol die vierde rekord terug wat dit reggekry het om in te voeg; die derde oproep misluk, en daar is drie rekords in die tabel.

Hoeveel rye sal in die tabel wees as gevolg van die loop van die volgende skrif?

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

BeantwoordVolgens Oracle-dokumentasie (aangehaal vanaf 11.2):

'n Kontrolebeperking laat jou 'n voorwaarde spesifiseer waaraan elke ry in die tabel moet voldoen. Om aan die beperking te voldoen, moet elke ry in die tabel die voorwaarde óf WAAR óf onbekend maak (as gevolg van 'n nul). Wanneer Oracle 'n tjekbeperkingsvoorwaarde vir 'n spesifieke ry evalueer, verwys enige kolomname in die toestand na die kolomwaardes in daardie ry.

Dus, die waarde nul sal die kontrole slaag, en die anonieme blokkering sal suksesvol uitgevoer word totdat 'n poging om die waarde 3 in te voeg. Hierna sal die fouthanteringsblok die uitsondering uitvee, geen terugrol sal plaasvind nie, en daar sal vier rye in die tabel oorbly met waardes 1, null, 2 en weer nul.

Watter pare waardes sal dieselfde hoeveelheid spasie in die blok opneem?

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 en X
  • B en Y
  • C en K
  • C en Z
  • K en Z
  • Ek en J
  • J en X
  • Alles gelys

BeantwoordHier is uittreksels uit die dokumentasie (12.1.0.2) oor die berging van verskeie tipes data in Oracle.

CHAR Data Tipe
Die CHAR datatipe spesifiseer 'n vaste-lengte karakterstring in die databasiskarakterstel. Jy spesifiseer die databasis karakterstel wanneer jy jou databasis skep. Oracle verseker dat alle waardes wat in 'n CHAR-kolom gestoor word, die lengte het wat volgens grootte in die geselekteerde lengte semantiek gespesifiseer word. As jy 'n waarde invoeg wat korter is as die kolomlengte, dan voeg Oracle die waarde leeg na kolomlengte.

VARCHAR2 Data Tipe
Die VARCHAR2-datatipe spesifiseer 'n karakterstring van veranderlike lengte in die databasiskarakterstel. Jy spesifiseer die databasis karakterstel wanneer jy jou databasis skep. Oracle stoor 'n karakterwaarde in 'n VARCHAR2-kolom presies soos jy dit spesifiseer, sonder enige leë opvulling, mits die waarde nie die lengte van die kolom oorskry nie.

NUMBER Datatipe
Die GETAL-datatipe stoor nul sowel as positiewe en negatiewe vaste getalle met absolute waardes van 1.0 x 10-130 tot maar nie 1.0 x 10126 ingesluit nie. As jy 'n rekenkundige uitdrukking spesifiseer waarvan die waarde 'n absolute waarde groter as of gelyk aan het 1.0 x 10126, dan gee Oracle 'n fout terug. Elke NUMBER waarde vereis van 1 tot 22 grepe. As u dit in ag neem, kan die kolomgrootte in grepe vir 'n spesifieke numeriese datawaarde NOMMER(p), waar p die akkuraatheid van 'n gegewe waarde is, bereken word deur die volgende formule te gebruik: RONDE((lengte(p)+s)/2))+1 waar s gelyk is aan nul as die getal positief is, en s gelyk is aan 1 as die getal negatief is.

Kom ons neem ook 'n uittreksel uit die dokumentasie oor die berging van nulwaardes.

'n Nul is die afwesigheid van 'n waarde in 'n kolom. Nulle dui op ontbrekende, onbekende of ontoepaslike data. Nulle word in die databasis gestoor as hulle tussen kolomme met datawaardes val. In hierdie gevalle benodig hulle 1 greep om die lengte van die kolom (nul) te stoor. Volgende nulpunte in 'n ry vereis geen berging nie, want 'n nuwe ryopskrif dui aan dat die oorblywende kolomme in die vorige ry nul is. Byvoorbeeld, as die laaste drie kolomme van 'n tabel nul is, word geen data vir hierdie kolomme gestoor nie.

Op grond van hierdie data bou ons redenasie. Ons neem aan dat die databasis AL32UTF8-kodering gebruik. In hierdie enkodering sal Russiese letters 2 grepe beset.

1) A en X, die waarde van veld a 'Y' neem 1 grepe, die waarde van veld x 'D' neem 2 grepe
2) B en Y, 'Vasya' in b die waarde sal opgevul word met spasies tot 10 karakters en sal 14 grepe neem, 'Vasya' in d sal 8 grepe neem.
3) C en K. Beide velde het die waarde NULL, daarna is daar beduidende velde, dus beslaan hulle 1 greep.
4) C en Z. Beide velde het die waarde NULL, maar veld Z is die laaste in die tabel, dus neem dit nie spasie op nie (0 grepe). Veld C beslaan 1 greep.
5) K en Z. Soortgelyk aan die vorige geval. Die waarde in die K-veld beslaan 1 greep, in Z – 0.
6) I en J. Volgens die dokumentasie sal beide waardes 2 grepe neem. Ons bereken die lengte deur gebruik te maak van die formule wat uit die dokumentasie geneem is: round( (1 + 0)/2) +1 = 1 + 1 = 2.
7) J en X. Die waarde in die J-veld sal 2 grepe neem, die waarde in die X-veld sal 2 grepe neem.

In totaal is die korrekte opsies: C en K, I en J, J en X.

Wat sal ongeveer die groeperingsfaktor van die T_I-indeks wees?

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

  • Omtrent tiene
  • Sowat honderde
  • Sowat duisende
  • Sowat tienduisende

BeantwoordVolgens Oracle-dokumentasie (aangehaal vanaf 12.1):

Vir 'n B-boom-indeks meet die indeksgroeperingsfaktor die fisiese groepering van rye in verhouding tot 'n indekswaarde.

Die indeksgroeperingsfaktor help die optimaliseerder om te besluit of 'n indeksskandering of 'n volledige tabelskandering meer doeltreffend is vir sekere navrae). 'n Lae groeperingsfaktor dui op 'n doeltreffende indeksskandering.

'n Groeperingsfaktor wat naby aan die aantal blokke in 'n tabel is, dui aan dat die rye fisies in die tabelblokke georden word deur die indekssleutel. As die databasis 'n volledige tabelskandering uitvoer, is die databasis geneig om die rye te herwin soos hulle op skyf gestoor word, gesorteer volgens die indekssleutel. 'n Groeperingsfaktor wat naby aan die aantal rye is, dui aan dat die rye ewekansig oor die databasisblokke in verhouding tot die indekssleutel versprei is. As die databasis 'n volledige tabelskandering uitvoer, sal die databasis nie rye in enige gesorteerde volgorde volgens hierdie indekssleutel ophaal nie.

In hierdie geval is die data ideaal gesorteer, so die groeperingsfaktor sal gelyk wees aan of naby aan die aantal besette blokke in die tabel. Vir 'n standaard blokgrootte van 8 kilogrepe, kan jy verwag dat ongeveer duisend smal getalwaardes in een blok sal pas, dus sal die aantal blokke, en as gevolg daarvan, die groeperingsfaktor wees omtrent tiene.

Teen watter waardes van N sal die volgende skrif suksesvol uitgevoer word in 'n gewone databasis met standaardinstellings?

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

BeantwoordVolgens Oracle-dokumentasie (aangehaal vanaf 11.2):

Logiese databasis limiete

item
Tipe limiet
Beperk waarde

Indekse
Totale grootte van geïndekseerde kolom
75% van die databasisblokgrootte minus 'n bietjie oorhoofse koste

Die totale grootte van geïndekseerde kolomme moet dus nie 6Kb oorskry nie. Wat volgende gebeur, hang af van die geselekteerde basiskodering. Vir AL32UTF8-kodering kan een karakter 'n maksimum van 4 grepe beslaan, so in die ergste geval sal 6 kilogrepe ongeveer 1500 karakters pas. Daarom sal Oracle indeksskepping verbied by N = 400 (wanneer die ergste geval sleutellengte 1600 karakters * 4 grepe + rylengte is), terwyl by N = 200 (of minder) die skep van die indeks sal sonder probleme werk.

Die INSERT-operateur met die APPEND-wenk is ontwerp om data in direkte modus te laai. Wat gebeur as dit toegepas word op die tafel waaraan die sneller hang?

  • Die data sal in direkte modus gelaai word, die sneller sal werk soos verwag
  • Die data sal in direkte modus gelaai word, maar die sneller sal nie uitgevoer word nie
  • Die data sal in konvensionele modus gelaai word, die sneller sal werk soos dit moet
  • Die data sal in konvensionele modus gelaai word, maar die sneller sal nie uitgevoer word nie
  • Die data sal nie gelaai word nie, 'n fout sal aangeteken word

BeantwoordBasies is dit meer 'n kwessie van logika. Om die korrekte antwoord te vind, sou ek die volgende redenasiemodel voorstel:

  1. Invoeging in direkte modus word uitgevoer deur direkte vorming van 'n datablok, wat die SQL-enjin omseil, wat hoë spoed verseker. Dit is dus baie moeilik, indien nie onmoontlik nie, om die uitvoering van die sneller te verseker, en dit is geen sin hierin nie, aangesien dit die invoeging steeds radikaal sal vertraag.
  2. Versuim om die sneller uit te voer sal daartoe lei dat, indien die data in die tabel dieselfde is, die toestand van die databasis as geheel (ander tabelle) sal afhang van die modus waarin hierdie data ingevoeg is. Dit sal natuurlik data-integriteit vernietig en kan nie as 'n oplossing in produksie toegepas word nie.
  3. Die onvermoë om die gevraagde bewerking uit te voer, word gewoonlik as 'n fout beskou. Maar hier moet ons onthou dat APPEND 'n wenk is, en die algemene logika van wenke is dat hulle in ag geneem word indien moontlik, maar indien nie, word die operateur uitgevoer sonder om die wenk in ag te neem.

Die verwagte antwoord is dus die data sal in normale (SQL) modus gelaai word, die sneller sal brand.

Volgens Oracle-dokumentasie (aangehaal vanaf 8.04):

Oortredings van die beperkings sal veroorsaak dat die stelling serieel uitgevoer word, deur gebruik te maak van die konvensionele invoegpad, sonder waarskuwings of foutboodskappe. 'n Uitsondering is die beperking op state wat meer as een keer in 'n transaksie toegang tot dieselfde tabel verkry, wat foutboodskappe kan veroorsaak.
Byvoorbeeld, as snellers of verwysingsintegriteit op die tafel teenwoordig is, sal die APPEND-wenk geïgnoreer word wanneer jy probeer om direkte-lading INSERT (serieel of parallel) te gebruik, sowel as die PARALLEL-wenk of klousule, indien enige.

Wat sal gebeur wanneer die volgende skrif uitgevoer word?

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

  • Suksesvolle voltooiing
  • Mislukking as gevolg van sintaksfout
  • Fout: outonome transaksie is nie geldig nie
  • Fout wat verband hou met die oorskryding van die maksimum oproepnes
  • Buitelandse sleutel-oortredingsfout
  • Fout wat verband hou met slotte

BeantwoordDie tabel en sneller is heeltemal korrek geskep en hierdie bewerking behoort nie tot probleme te lei nie. Outonome transaksies in 'n sneller word ook toegelaat, anders sou logging byvoorbeeld nie moontlik wees nie.

Nadat die eerste ry ingevoeg is, sal 'n suksesvolle snellervuur ​​veroorsaak dat die tweede ry ingevoeg word, wat veroorsaak dat die sneller weer vuur, 'n derde ry ingevoeg word, ensovoorts totdat die stelling misluk het as gevolg van die oorskryding van die maksimum nes van oproepe. Nog 'n subtiele punt kom egter ter sprake. Toe die sneller uitgevoer word, is commit nog nie voltooi vir die eerste ingevoegde rekord nie. Daarom probeer 'n sneller wat in 'n outonome transaksie loop om 'n ry in die tabel in te voeg wat 'n vreemde sleutel verwys na 'n rekord wat nog nie gepleeg is nie. Dit lei tot 'n wag (die outonome transaksie wag vir die hooftransaksie om te verbind om te sien of dit data kan invoeg) en terselfdertyd wag die hooftransaksie vir die outonome transaksie om na die sneller voort te werk. 'n Dooiepunt vind plaas en gevolglik word die outonome transaksie gekanselleer weens redes wat verband hou met slotte.

Slegs geregistreerde gebruikers kan aan die opname deelneem. Meld aan, asseblief.

Dit was moeilik om?

  • Soos twee vingers het ek dadelik alles reg besluit.

  • Nie regtig nie, ek was verkeerd met 'n paar vrae.

  • Ek het die helfte daarvan reg opgelos.

  • Ek het die antwoord twee keer geraai!

  • Ek sal in die kommentaar skryf

14 gebruikers het gestem. 10 gebruikers het buite stemming gebly.

Bron: will.com

Voeg 'n opmerking