Li dû şopên Highload++ Siberia 2019 - 8 peywirên li ser Oracle

Hello!

Di 24-25ê Hezîranê de li Novosibirsk konferansa Highload++ Siberia 2019 hat lidarxistin, hevalên me jî li wir bûn. nûçe "Daneyên konteynerê Oracle (CDB/PDB) û karanîna wan a pratîkî ji bo pêşkeftina nermalavê", em ê guhertoyek nivîsê hinekî paşê biweşînin. Ew xweş bû, spas olegbunin ji bo rêxistinê, her weha ji bo her kesê ku hatî.

Li dû şopên Highload++ Siberia 2019 - 8 peywirên li ser Oracle
Di vê postê de, em dixwazin pirsgirêkên ku me li stûna xwe hebûn bi we re parve bikin da ku hûn zanîna xwe ya Oracle biceribînin. Li jêrê 8 pirsgirêk, vebijarkên bersivê û ravekirin hene.

Nirxa rêza herî zêde ya ku em ê di encama pêkanîna skrîpta jêrîn de bibînin çi ye?

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
  • Na, dê xeletiyek hebe

BersivLi gorî belgeya Oracle (ji 8.1.6 ve hatî vegotin):
Di nav yek danezanek SQL de, Oracle dê rêzê tenê carekê li ser rêzek zêde bike. Heke daxuyaniyek ji bo rêzek ji yekê zêdetir referansên NEXTVAL-ê hebe, Oracle rêzikê carekê zêde dike û ji bo hemî bûyerên NEXTVAL-ê heman nirxê vedigerîne. Heke daxuyaniyek hem CURRVAL û hem jî NEXTVAL-ê referansên xwe hebin, Oracle rêzê zêde dike û heman nirxê hem ji bo CURRVAL û hem jî ji bo NEXTVAL vedigerîne bêyî ku rêza wan di nav daxuyaniyê de be.

Bi vî awayî, nirxa herî zêde dê bi hejmara rêzan re têkildar be, ango 5 e.

Di encama xebitandina skrîpta jêrîn de dê çend rêz di tabloyê de bin?

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

BersivLi gorî belgeya Oracle (ji 11.2 ve hatî vegotin):

Berî ku hûn daxuyaniyek SQL bicîh bikin, Oracle nuqteyek hilanînê ya nepenî nîşan dide (ji we re tune). Dûv re, heke daxuyanî têk neçe, Oracle wê bixweber paşde vedigerîne û koda xeletiya bicîhkirî vedigerîne SQLCODE di SQLCA de. Mînakî, heke daxûyaniyek INSERT bi hewldana xistina nirxek dubare di navnîşek yekta de bibe sedema xeletiyekê, daxuyanî paşve tê avêtin.

Banga HP-ê ji xerîdar jî wekî daxuyaniyek yekane tête hesibandin û pêvajo kirin. Bi vî rengî, yekem banga HP-ê bi serfirazî temam dibe, ku sê tomar têxe nav xwe; bangewaziya HP-ê ya duyemîn bi xeletiyek bi dawî dibe û tomara çaremîn a ku wê têxe nav xwe vedigerîne; banga sêyemîn têk diçe, û di tabloyê de sê tomar hene.

Di encama xebitandina skrîpta jêrîn de dê çend rêz di tabloyê de bin?

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

BersivLi gorî belgeya Oracle (ji 11.2 ve hatî vegotin):

Destûrek kontrolê dihêle hûn şertek diyar bikin ku divê her rêzek di tabloyê de têr bike. Ji bo tetmînkirina astengiyê, divê her rêzek di tabloyê de şertê TRUE an jî nenas bike (ji ber nûlekê). Dema ku Oracle ji bo rêzek taybetî şertek astengiya kontrolê dinirxîne, her navên stûnê yên di rewşê de li nirxên stûnê yên di wê rêzê de vedigerin.

Ji ber vê yekê, nirxa null dê kontrolê derbas bike, û bloka nenas dê bi serfirazî were darve kirin heya ku hewildanek ji bo têxistina nirxa 3. Piştî vê yekê, bloka birêvebirina xeletiyê dê îstîsnayê paqij bike, paşvegerandin çênabe, û dê çar rêz di tabloyê de bimîne bi nirxên 1, null, 2 û dîsa null.

Kîjan cotên nirxan dê di blokê de heman cîhê bigirin?

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 û X
  • B û Y
  • C û K
  • C û Z
  • K û Z
  • Ez û J
  • J û X
  • Hemî navnîşkirî

BersivLi vir perçeyên ji belgeyên (12.1.0.2) yên li ser hilanîna cûrbecûr daneyên li Oracle hene.

Tîpa Daneyên CHAR
Tîpa daneya CHAR di koma karaktera databasê de xêzek karakterek bi dirêjiya sabît diyar dike. Dema ku hûn databasa xwe diafirînin hûn karektera databasê diyar dikin. Oracle piştrast dike ku hemî nirxên ku di stûnek CHAR de têne hilanîn dirêjahiya ku ji hêla mezinbûnê ve di semantîka dirêjahiya bijartî de hatî destnîşan kirin heye. Ger hûn nirxek ku ji dirêjahiya stûnê kurttir e têxin nav xwe, wê hingê Oracle nirxê li dirêjahiya stûnê dixe.

Tîpa Daneyên VARCHAR2
Tîpa daneya VARCHAR2 di koma karaktera databasê de xêzek karakterek bi dirêjiya guhêrbar diyar dike. Dema ku hûn databasa xwe diafirînin hûn karektera databasê diyar dikin. Oracle nirxek karekterê di stûnek VARCHAR2 de tam wekî ku hûn diyar dikin hilîne, bêyî pêvekirina vala, bi şertê ku nirx ji dirêjahiya stûnê derbas nebe.

Tîpa Daneyên HEJMAR
Tîpa daneya HEJMAR, sifir û hem jî hejmarên sabît ên erênî û neyînî bi nirxên mutlaq ji 1.0 x 10-130 heta 1.0 x 10126 dihewîne, hildide. Ger hûn diyardeyek hejmartî diyar bikin ku nirxa wê nirxek mutleq jê mezintir an wekhev e. 1.0 x 10126, paşê Oracle xeletiyek vedigere. Her nirxek HEJMAR ji 1 heta 22 bayt hewce dike. Li gorî vê yekê, mezinahiya stûnê di bîtan de ji bo nirxek daneya hejmarî ya taybetî HEJMAR(p), ku p rastbûna nirxek diyarkirî ye, dikare bi formula jêrîn were hesibandin: ROUND((dirêj(p)+s)/2))+1 ku s dibe sifir heke hejmar erênî be, û s dibe 1 heke hejmar neyînî be.

Digel vê yekê, bila em ji belgenameyê der barê hilanîna nirxên Null de perçeyek bigirin.

Null tunebûna nirxek di stûnekê de ye. Null daneyan winda, nenas, an ne sepandin nîşan dide. Null di databasê de têne hilanîn heke ew di navbera stûnên bi nirxên daneyê de bin. Di van rewşan de, ew 1 byte hewce dikin ku dirêjahiya stûnê (sifir) hilînin. Di rêzê de nûleyên paşverû ne hewceyî hilanînê ne ji ber ku sernavê rêzek nû nîşan dide ku stûnên mayî yên di rêza berê de vala ne. Mînakî, heke sê stûnên paşîn ên tabloyek betal bin, wê hingê ji bo van stûnan dane nayê hilanîn.

Li ser van daneyan, em ramanê ava dikin. Em texmîn dikin ku databas şîfrekirina AL32UTF8 bikar tîne. Di vê şîfrekirinê de, tîpên rûsî dê 2 byte dagir bikin.

1) A û X, nirxa zeviyê a 'Y' 1 byte digire, nirxa qada x 'D' 2 byte digire
2) B û Y, 'Vasya' di b de dê nirx bi valahiyên heya 10 tîpan were dagirtin û dê 14 byte bigire, 'Vasya' di d de dê 8 byte bigire.
3) C û K. Her du qadan xwedî nirxa NULL ne, piştî wan qadên girîng hene, ji ber vê yekê ew 1 byte digirin.
4) C û Z. Nirxa her du qadan jî NULL ye, lê qada Z di tabloyê de ya dawî ye, ji ber vê yekê cîh nagire (0 byte). Qada C 1 byte digire.
5) K û Z. Mîna rewşa berê. Nirxa di qada K de 1 byte, di Z - 0 de digire.
6) Ez û J. Li gorî belgeyê, her du nirx dê 2 byte bigirin. Em dirêjahiyê bi formula ku ji belgeyê hatî girtin hesab dikin: dor( (1 + 0)/2) +1 = 1 + 1 = 2.
7) J û X. Nirxa di qada J de dê 2 byte, nirxa di qada X de dê 2 byte bigire.

Bi tevahî, vebijarkên rast ev in: C û K, I û J, J û X.

Dê bi texmînî faktora komkirinê ya nîşana T_I çi be?

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

  • Nêzîkî dehan
  • Bi sedan
  • Bi hezaran
  • Nêzîkî deh hezaran

BersivLi gorî belgeya Oracle (ji 12.1 ve hatî vegotin):

Ji bo nîşanek dara B-yê, faktora komkirina îndeksê koma fizîkî ya rêzikan li gorî nirxek îndeksê dipîve.

Faktora komkirina îndeksê ji optimîzatorê re dibe alîkar ku biryarê bide ka şanek nîşanek an tabloya tevahî ji bo hin pirsan bikêrtir e). Faktorek kombûnê ya nizm sehkirinek nîşanek bikêr nîşan dide.

Faktorek kombûnê ya ku nêzî hejmara blokên di tabloyê de ye, destnîşan dike ku rêz di blokên tabloyê de ji hêla mifteya indexê ve bi fîzîkî têne rêz kirin. Ger databas tabloya tabloya tevahî pêk bîne, wê hingê databas mêl dike ku rêzan bigire ji ber ku ew li ser dîskê têne hilanîn ku ji hêla mifteya navnîşê ve hatî rêz kirin. Faktorek kombûnê ya ku nêzî hejmara rêzan e, destnîşan dike ku rêzik li gorî bişkojka pêvekê bi rengek bêhemdî li blokên databasê têne belav kirin. Ger databas tabloya tabloya tevahî pêk bîne, wê hingê databas dê rêzikan bi tu rêzek rêzkirî li gorî vê mifteya pêvekê venegire.

Di vê rewşê de, dane bi îdeal têne rêz kirin, ji ber vê yekê faktora kombûnê dê bi hejmara blokên dagirkirî yên di tabloyê de wekhev an nêzik be. Ji bo mezinahiya bloka standard a 8 kilobyte, hûn dikarin li bendê bin ku bi qasî hezar nirxên jimareya teng dê di yek blokekê de cih bigirin, ji ber vê yekê hejmara blokan, û di encamê de, faktora kombûnê dê bibe. nêzîkî dehan.

Di kîjan nirxên N-ê de dê skrîpta jêrîn di databasek birêkûpêk de bi mîhengên standard bi serfirazî were darve kirin?

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

BersivLi gorî belgeya Oracle (ji 11.2 ve hatî vegotin):

Sînorên Database Mantiqî

Şanî
Type of Limit
Nirxa Sînorê

Indexes
Mezinahiya tevahî ya stûna pêvekirî
75% ji mezinahiya bloka databasê kêm zêde hin zêde

Ji ber vê yekê, mezinahiya giştî ya stûnên navnîşkirî divê ji 6 Kb derbas nebe. Dûv re çi diqewime bi kodkirina bingehîn a hilbijartî ve girêdayî ye. Ji bo şîfrekirina AL32UTF8, yek karakter dikare herî zêde 4 byte dagir bike, ji ber vê yekê di senaryoya herî xirab de, nêzîkê 6 tîpan dê di nav 1500 kilobyte de cih bigirin. Ji ber vê yekê, Oracle dê destûr nede çêkirina îndeksê li N = 400 (dema ku dirêjahiya keya herî xirab 1600 karakter * 4 byte + dirêjahiya rêzê be), dema ku li N = 200 (an kêmtir) çêkirina îndeksê dê bê pirsgirêk bixebite.

Operatorê INSERT bi nîşana APPEND ve hatî sêwirandin ku daneyan di moda rasterast de bar bike. Ger ew li ser maseya ku tetik li ser daleqandî were sepandin çi dibe?

  • Daneyên dê di moda rasterast de werin barkirin, tetik dê wekî ku tê hêvî kirin bixebite
  • Daneyên dê di moda rasterast de werin barkirin, lê tetik dê neyê darve kirin
  • Daneyên dê di moda kevneşopî de werin barkirin, tetik dê wekî ku divê bixebite
  • Daneyên dê di moda kevneşopî de werin barkirin, lê tetik dê neyê darve kirin
  • Dê dane neyê barkirin, dê xeletiyek were tomar kirin

BersivDi bingeh de, ev bêtir pirsek mantiqê ye. Ji bo dîtina bersiva rast, ez modela ramana jêrîn pêşniyar dikim:

  1. Veguheztina di moda rasterast de bi damezrandina rasterast a bloka daneyê ve, ji motora SQL-ê derbas dibe, ku leza bilind peyda dike. Bi vî rengî, dabînkirina bicîhkirina tetikê pir dijwar e, heke ne ne mumkun be, û ti xalek di vê de tune, ji ber ku ew ê hîn jî bi rengek radîkal têketinê hêdî bike.
  2. Nexebitandina tetikê dê bibe sedema vê yekê ku, heke daneyên di tabloyê de yek bin, dê rewşa databasê bi tevahî (tabloyên din) bi moda ku ev dane tê de hatî veqetandin ve girêdayî be. Ev eşkere dê yekbûna daneyê hilweşîne û nikare wekî çareseriyek di hilberînê de were sepandin.
  3. Nekarîniya pêkanîna operasyona daxwazkirî bi gelemperî wekî xeletiyek tê hesibandin. Lê li vir divê em ji bîr mekin ku APPEND îşaretek e, û mantiqa giştî ya şîretan ev e ku heke gengaz be ew têne hesibandin, lê heke ne wusa be, operator bêyî ku îşaretekê li ber çavan bigire tê darve kirin.

Ji ber vê yekê bersiva hêvîdar e Daneyên wê di moda normal (SQL) de werin barkirin, tetik dê bişewite.

Li gorî belgeya Oracle (ji 8.04 ve hatî vegotin):

Binpêkirina qedexeyan dê bibe sedem ku daxuyanî bi rêzî, bi karanîna riya têketina kevneşopî, bêyî hişyarî an peyamên xeletiyê were darve kirin. Îstîsnayek sînorkirina danezan e ku di danûstendinê de ji carekê zêdetir bigihîjin heman tabloyê, ku dikare bibe sedema peyamên xeletiyê.
Mînakî, heke li ser sifrê teşqele an yekparebûna referansê hebe, wê gavê gava ku hûn hewl bidin ku INSERT-a rasterast-barkirinê (rêzik an paralel), û her weha nîşanek an bendek PARALLEL, heke hebe, şîreta PÊVEK were paşguh kirin.

Dema ku skrîpta jêrîn were darve kirin dê çi bibe?

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

  • îdamkirina serketî
  • Ji ber xeletiya hevoksaziyê têkçû
  • Çewtî: Danûstendina Xweser Ne Derbasdar e
  • Çewtiya ku bi zêdekirina hêlîna bangê ya herî zêde ve girêdayî ye
  • Çewtiya Binpêkirina Key Biyanî
  • Çewtiya bi qefleyan ve girêdayî ye

BersivTablo û tetik bi rengek rast têne afirandin û divê ev operasyon nebin sedema pirsgirêkan. Danûstandinên xweser ên di tetikê de jî têne destûr kirin, wekî mînak, têketin dê ne gengaz be.

Piştî têxistina rêza yekem, teqandinek serketî ya tetikê dê bibe sedema ku rêza duyemîn were danîn, û bibe sedema ku tetik dîsa bişewite, rêzek sêyemîn têxe, û hwd. Lêbelê, xalek din a nazik derdikeve pêş. Di dema ku tetikê tê darve kirin, ji bo yekem qeyda têxe commit hîn temam nebûye. Ji ber vê yekê, tetikek ku di danûstendinek xweser de dixebite hewl dide ku rêzek ku kilîtek biyanî vedibêje tomarek ku hîn nehatiye bicîh kirin têxe tabloyê. Ev encam li bendê ye (danûstendina xweser li benda danûstendina sereke dimîne da ku bibîne ka ew dikare daneyan têxe ka) û di heman demê de danûstendina sereke li bendê ye ku danûstendina xweser piştî destavêtinê xebata xwe bidomîne. Girtîbûnek çêdibe û, di encamê de, danûstendina xweser ji ber sedemên girêdayî qefleyan betal dibe.

Tenê bikarhênerên qeydkirî dikarin beşdarî anketê bibin. Têketinji kerema xwe.

Zehmet bû ku?

  • Mîna du tiliyan, min tavilê her tişt rast biryar da.

  • Ne bi rastî, ez di çend pirsan de xelet bûm.

  • Min nîvê wê rast çareser kir.

  • Min bersiv du caran texmîn kir!

  • Ez ê di şîroveyan de binivîsim

14 bikarhêneran deng dan. 10 bikarhêner jî betal bûn.

Source: www.habr.com

Add a comment