Folgje yn 'e fuotstappen fan Highload++ Siberia 2019 - 8 taken op Oracle

Hallo!

Op 24-25 juny waard yn Novosibirsk de konferinsje Highload++ Siberia 2019 hâlden. Us jonges wiene der ek melde "Oracle container databases (CDB / PDB) en harren praktyske gebrûk foar software ûntwikkeling", wy sille publisearje in tekst ferzje in bytsje letter. It wie cool, tank olegbunin foar de organisaasje, likegoed as foar elkenien dy't kaam.

Folgje yn 'e fuotstappen fan Highload++ Siberia 2019 - 8 taken op Oracle
Yn dit post wolle wy de problemen mei jo diele dy't wy op ús stand hiene, sadat jo jo Oracle-kennis kinne testen. Under de besuniging binne 8 problemen, antwurd opsjes en útlis.

Wat is de maksimale folchoarderwearde dy't wy sille sjen as gefolch fan it útfieren fan it folgjende skript?

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, der sil in flater wêze

ReplyNeffens Oracle-dokumintaasje (oanhelle fan 8.1.6):
Binnen ien SQL-statement sil Oracle de folchoarder mar ien kear per rige ferheegje. As in ferklearring befettet mear as ien ferwizing nei NEXTVAL foar in sekwinsje, fergruttet Oracle de folchoarder ien kear en jout deselde wearde foar alle foarkommen fan NEXTVAL. As in ferklearring befettet ferwizings nei sawol CURRVAL as NEXTVAL, fergruttet Oracle de folchoarder en jout deselde wearde foar sawol CURRVAL as NEXTVAL nettsjinsteande harren folchoarder binnen de ferklearring.

sa, de maksimale wearde sil oerienkomme mei it oantal rigels, dat is 5.

Hoefolle rigen sille yn 'e tabel wêze as gefolch fan it útfieren fan it folgjende skript?

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

ReplyNeffens Oracle-dokumintaasje (oanhelle fan 11.2):

Foardat jo in SQL-statement útfiere, markearret Oracle in ymplisite opslachpunt (net beskikber foar jo). Dan, as de ferklearring mislearret, rôlet Oracle it automatysk werom en jout de jildende flaterkoade werom nei SQLCODE yn 'e SQLCA. Bygelyks, as in INSERT-útspraak in flater feroarsaket troch te besykjen in dûbele wearde yn in unike yndeks yn te foegjen, wurdt de ferklearring weromrôle.

Oprop HP fan de klant wurdt ek beskôge en ferwurke as ien ferklearring. Sa, de earste HP oprop foltôging mei súkses, nei't ynfoege trije records; de twadde HP-oprop einiget mei in flater en rôlet it fjirde rekôr werom dat it slagge om yn te foegjen; de tredde oprop mislearret, en der binne trije records yn 'e tabel.

Hoefolle rigen sille yn 'e tabel wêze as gefolch fan it útfieren fan it folgjende skript?

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

ReplyNeffens Oracle-dokumintaasje (oanhelle fan 11.2):

In kontrôlebeheining lit jo in betingst opjaan dy't elke rige yn 'e tabel foldwaan moat. Om de beheining te befredigjen, moat elke rige yn 'e tabel de betingst of TRUE of ûnbekend meitsje (fanwege in nul). As Oracle in betingst foar kontrôlebeheining evaluearret foar in bepaalde rige, ferwize alle kolomnammen yn 'e betingst nei de kolomwearden yn dy rige.

Sa sil de wearde null de kontrôle trochjaan, en it anonime blok sil mei súkses útfierd wurde oant in besykjen om de wearde 3 yn te foegjen. Hjirnei sil it flaterhannelingsblok de útsûndering wiskje, gjin weromdraaie sil plakfine, en der sille fjouwer rigen oerbleaun yn 'e tabel mei wearden 1, null, 2 en wer nul.

Hokker pear wearden sille itselde bedrach fan romte yn it blok nimme?

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
  • ik en J
  • J en X
  • Alle listed

ReplyHjir binne úttreksels út 'e dokumintaasje (12.1.0.2) oer it bewarjen fan ferskate soarten gegevens yn Oracle.

CHAR Data Type
It CHAR-gegevenstype spesifisearret in tekenrige mei fêste lingte yn de databanktekenset. Jo spesifisearje de databankkarakterset as jo jo databank oanmeitsje. Oracle soarget derfoar dat alle wearden opslein yn in CHAR-kolom de lingte hawwe spesifisearre troch grutte yn 'e selektearre lingte semantyk. As jo ​​in wearde ynfoegje dy't koarter is as de kolomlingte, dan set Oracle blank-pads de wearde nei kolomlingte.

VARCHAR2 Data Type
It VARCHAR2-gegevenstype spesifisearret in tekenrige mei fariabele lingte yn 'e databanktekenset. Jo spesifisearje de databankkarakterset as jo jo databank oanmeitsje. Oracle bewarret in karakterwearde yn in VARCHAR2-kolom krekt sa't jo it oantsjutte, sûnder lege padding, op betingst dat de wearde de lingte fan 'e kolom net grutter is.

NUMBER Gegevenstype
It gegevenstype NUMBER bewarret nul as positive en negative fêste sifers mei absolute wearden fan 1.0 x 10-130 oant mar net ynklusyf 1.0 x 10126. 1.0 x 10126, dan jout Oracle in flater werom. Elke NUMBER wearde fereasket fan 1 oant 22 bytes. Mei dit yn rekken brocht, kin de kolomgrutte yn bytes foar in bepaalde numerike gegevenswearde NUMBER (p), wêrby't p de krektens is fan in opjûne wearde, berekkene wurde mei de folgjende formule: ROUND((lengte(p)+s)/2))+1 wêr s nul is as it getal posityf is, en s is gelyk oan 1 as it getal negatyf is.

Lit ús boppedat in úttreksel nimme út 'e dokumintaasje oer it bewarjen fan Null-wearden.

In nul is it ûntbrekken fan in wearde yn in kolom. Nulls jouwe ûntbrekkende, ûnbekende of net-tapasbere gegevens oan. Nulls wurde opslein yn de databank as se falle tusken kolommen mei gegevens wearden. Yn dizze gefallen hawwe se 1 byte nedich om de lingte fan 'e kolom (nul) op te slaan. Folgjende nulls yn in rige fereaskje gjin opslach omdat in nije rige koptekst sinjalearret dat de oerbleaune kolommen yn de foarige rige binne nul. Bygelyks, as de lêste trije kolommen fan in tabel nul binne, dan wurde gjin gegevens opslein foar dizze kolommen.

Op grûn fan dizze gegevens bouwe wy redenearring. Wy geane derfan út dat de databank brûkt AL32UTF8 kodearring. Yn dizze kodearring sille Russyske letters 2 bytes ynnimme.

1) A en X, de wearde fan fjild a 'Y' nimt 1 byte, de wearde fan fjild x 'D' nimt 2 bytes
2) B en Y, 'Vasya' yn b de wearde wurdt opknapt mei spaasjes oant 10 tekens en sil nimme 14 bytes, 'Vasya' yn d sil nimme 8 bytes.
3) C en K. Beide fjilden hawwe de wearde NULL, nei harren binne der wichtige fjilden, sadat se besette 1 byte.
4) C en Z. Beide fjilden hawwe de wearde NULL, mar fjild Z is de lêste yn 'e tabel, dus it nimt gjin romte (0 bytes). Fjild C beslacht 1 byte.
5) K en Z. Similar to de foarige gefal. De wearde yn it K-fjild beslacht 1 byte, yn Z - 0.
6) I en J. Neffens de dokumintaasje sille beide wearden 2 bytes nimme. Wy berekkenje de lingte mei de formule nommen út 'e dokumintaasje: rûn ((1 + 0)/2) +1 = 1 + 1 = 2.
7) J en X. De wearde yn it J-fjild sil 2 bytes nimme, de wearde yn it X-fjild sil 2 bytes nimme.

Yn totaal binne de juste opsjes: C en K, I en J, J en X.

Wat sil sawat de klusterfaktor wêze fan 'e T_I-yndeks?

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

  • Oer tsientallen
  • Oer hûnderten
  • Oer tûzenen
  • Sawat tsientûzenen

ReplyNeffens Oracle-dokumintaasje (oanhelle fan 12.1):

Foar in B-beam-yndeks mjit de yndeksklusterfaktor de fysike groepearring fan rigen yn relaasje ta in yndekswearde.

De yndeksklusterfaktor helpt de optimizer te besluten oft in yndeksscan of folsleine tabelscan effisjinter is foar bepaalde fragen). In lege klusterfaktor jout in effisjinte yndeksscan oan.

In klustering faktor dat is tichtby it oantal blokken yn in tabel jout oan dat de rigen wurde fysyk oardere yn de tabel blokken troch de yndeks kaai. As de databank in folsleine tabelscan útfiert, dan hat de databank de oanstriid om de rigen op te heljen sa't se op skiif wurde opslein, sorteare troch de yndekskaai. In klustering faktor dat is tichtby it oantal rigen jout oan dat de rigen wurde ferspraat willekeurich oer de databank blokken yn relaasje ta de yndeks kaai. As de databank in folsleine tabelscan útfiert, dan soe de databank gjin rigen ophelje yn elke sorteare folchoarder troch dizze yndekskaai.

Yn dit gefal wurde de gegevens by útstek sortearre, sadat de klusterfaktor lykweardich is oan of tichtby it oantal besette blokken yn 'e tabel. Foar in standert blokgrutte fan 8 kilobytes kinne jo ferwachtsje dat sawat tûzen smelle nûmerwearden yn ien blok passe, sadat it oantal blokken, en as gefolch, de klusterfaktor sil wêze oer tsien.

Op hokker wearden fan N sil it folgjende skript mei súkses wurde útfierd yn in gewoane database mei standertynstellingen?

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

ReplyNeffens Oracle-dokumintaasje (oanhelle fan 11.2):

Logyske databankgrinzen

Ûnderdiel
Soart limyt
Limyt Wearde

Yndeksen
Totale grutte fan yndeksearre kolom
75% fan 'e databankblokgrutte minus wat overhead

Sa soe de totale grutte fan yndeksearre kolommen net mear wêze moatte as 6Kb. Wat dan bart, hinget ôf fan de selektearre basiskodearring. Foar AL32UTF8-kodearring kin ien karakter maksimaal 4 bytes ynnimme, dus yn it slimste gefal passe sa'n 6 tekens yn 1500 kilobytes. Dêrom sil Oracle it meitsjen fan yndeks net tastean by N = 400 (as de kaailingte yn it slimste gefal 1600 karakters * 4 bytes + rowide lingte is), wylst by N = 200 (of minder) it meitsjen fan de yndeks sil wurkje sûnder problemen.

De INSERT-operator mei de APPEND-hint is ûntworpen om gegevens yn direkte modus te laden. Wat bart der as it wurdt tapast op de tafel dêr't de trekker hinget?

  • De gegevens sille yn direkte modus laden wurde, de trigger sil wurkje lykas ferwachte
  • De gegevens wurde laden yn direkte modus, mar de trigger sil net wurde útfierd
  • De gegevens sille wurde laden yn konvinsjonele modus, de trigger sil wurkje sa't it moat
  • De gegevens wurde laden yn konvinsjonele modus, mar de trigger sil net wurde útfierd
  • De gegevens wurde net laden, in flater sil wurde opnommen

ReplyYn prinsipe is dit mear in kwestje fan logika. Om it juste antwurd te finen, soe ik it folgjende redenaasjemodel foarstelle:

  1. Ynfoegje yn direkte modus wurdt útfierd troch direkte formaasje fan in gegevensblok, troch de SQL-motor te omgean, dy't in hege snelheid soarget. Sa, it garandearjen fan de útfiering fan de trekker is hiel lestich, as net ûnmooglik, en it hat gjin punt yn dit, om't it sil noch radikaal fertrage de ynfoegje.
  2. It net útfieren fan de trigger sil liede ta it feit dat, as de gegevens yn 'e tabel itselde binne, de steat fan' e databank as gehiel (oare tabellen) sil ôfhingje fan 'e modus wêryn dizze gegevens binne ynfoege. Dit sil fansels de yntegriteit fan gegevens ferneatigje en kin net tapast wurde as oplossing yn produksje.
  3. It ûnfermogen om de frege operaasje út te fieren wurdt algemien behannele as in flater. Mar hjir moatte wy betinke dat APPEND is in hint, en de algemiene logika fan hints is dat se wurde rekken holden as it mooglik is, mar sa net, de operator wurdt útfierd sûnder rekken hâldend mei de hint.

Dus it ferwachte antwurd is de gegevens sille wurde laden yn normale (SQL) modus, de trigger sil fjoer.

Neffens Oracle-dokumintaasje (oanhelle fan 8.04):

Oertredings fan de beheiningen sille meitsje dat de ferklearring serieus wurdt útfierd, mei it konvinsjonele ynfoegjepaad, sûnder warskôgings of flaterberjochten. In útsûndering is de beheining op útspraken dy't tagong krije ta deselde tabel mear as ien kear yn in transaksje, wat kin feroarsaakje flater berjochten.
Bygelyks, as triggers of referinsjele yntegriteit oanwêzich binne op 'e tafel, dan sil de APPEND hint wurde negearre as jo besykje te brûken direkte-load INSERT (searje of parallel), lykas ek de PARALLEL hint of klausule, as der ien is.

Wat sil barre as it folgjende skript wurdt útfierd?

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

  • Súksesfolle útfiering
  • Mislearring fanwege syntaksisflater
  • Flater: Autonome transaksje is net jildich
  • Flater relatearre oan it oertsjûgjen fan de maksimale oprop nêst
  • Bûtenlânske Key Violation Flater
  • Flater yn ferbân mei slûzen

ReplyDe tabel en de trigger binne krekt goed makke en dizze operaasje moat net liede ta problemen. Autonome transaksjes yn in trigger binne ek tastien, oars soe logging bygelyks net mooglik wêze.

Nei it ynfoegjen fan 'e earste rige soe in suksesfolle trigger-firing de twadde rige ynfoege wurde, wêrtroch't de trekker opnij sjitte, in tredde rige ynfoegje, ensfh. In oar subtyl punt komt lykwols yn it spul. Op it momint dat de trigger wurdt útfierd, is commit noch net foltôge foar de earste ynfoege record. Dêrom besiket in trigger dy't rint yn in autonome transaksje yn 'e tabel in rige yn te foegjen dy't in frjemde kaai ferwiist nei in rekord dat noch net is ynset. Dit resultearret yn in wachtsjen (de autonome transaksje wachtet op 'e haadtransaksje om te begean om te sjen oft it gegevens ynfoegje kin) en tagelyk wachtet de haadtransaksje op' e autonome transaksje om fierder te wurkjen nei de trigger. In deadlock komt foar en as gefolch wurdt de autonome transaksje annulearre fanwege redenen dy't relatearre binne oan slûzen.

Allinnich registrearre brûkers kinne meidwaan oan 'e enkête. Ynlogge, asjebleaft.

It wie dreech om?

  • As twa fingers besleat ik fuortendaliks alles goed.

  • Net echt, ik wie ferkeard op in pear fragen.

  • Ik haw de helte goed oplost.

  • Ik ried it antwurd twa kear!

  • Ik sil skriuwe yn 'e kommentaren

14 brûkers stimden. 10 brûkers ûntholden har.

Boarne: www.habr.com

Add a comment