Пратећи стопе Хигхлоад++ Сибериа 2019 - 8 задатака на Орацле-у

Здраво!

24-25. јуна одржана је конференција Хигхлоад++ Сибериа 2019 у Новосибирску извештај „Орацле контејнерске базе података (ЦДБ/ПДБ) и њихова практична употреба за развој софтвера“, објавићемо текстуалну верзију мало касније. Било је супер, хвала олегбунин за организацију, као и свима који су дошли.

Пратећи стопе Хигхлоад++ Сибериа 2019 - 8 задатака на Орацле-у
У овом посту желимо да поделимо са вама проблеме које смо имали на нашем штанду како бисте могли да тестирате своје Орацле знање. Испод реза је 8 задатака, опција одговора и објашњења.

Која је максимална вредност секвенце коју ћемо видети као резултат извршавања следеће скрипте?

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
  • Не, биће грешке

ОдговорПрема Орацле документацији (цитирано од 8.1.6):
У оквиру једне СКЛ изјаве, Орацле ће повећати секвенцу само једном по реду. Ако израз садржи више од једне референце на НЕКСТВАЛ за секвенцу, Орацле повећава секвенцу једном и враћа исту вредност за сва појављивања НЕКСТВАЛ. Ако израз садржи референце и на ЦУРРВАЛ и на НЕКСТВАЛ, Орацле повећава секвенцу и враћа исту вредност за ЦУРРВАЛ и НЕКСТВАЛ без обзира на њихов редослед у наредби.

Дакле, максимална вредност ће одговарати броју редова, односно 5.

Колико ће редова бити у табели као резултат покретања следеће скрипте?

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

ОдговорПрема Орацле документацији (цитирано од 11.2):

Пре извршавања било које СКЛ наредбе, Орацле означава имплицитну тачку чувања (није доступна вама). Затим, ако израз не успе, Орацле га аутоматски враћа назад и враћа одговарајући код грешке у СКЛЦОДЕ у СКЛЦА. На пример, ако израз ИНСЕРТ изазове грешку покушавајући да убаци дупликат вредности у јединствени индекс, израз се враћа назад.

Позивање ХП-а од клијента се такође сматра и обрађује као једна изјава. Дакле, први ХП позив се завршава успешно, након убацивања три записа; други ХП позив се завршава грешком и враћа четврти запис који је успео да убаци; трећи позив не успева, а у табели су три записа.

Колико ће редова бити у табели као резултат покретања следеће скрипте?

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

ОдговорПрема Орацле документацији (цитирано од 11.2):

Ограничење провере вам омогућава да наведете услов који сваки ред у табели мора да задовољи. Да би се задовољило ограничење, сваки ред у табели мора да учини услов или ТРУЕ или непознат (због нуле). Када Орацле процени услов ограничења провере за одређени ред, називи свих колона у услову односе се на вредности колона у том реду.

Дакле, вредност нулл ће проћи проверу, а анонимни блок ће бити успешно извршен до покушаја убацивања вредности 3. Након тога, блок за обраду грешака ће обрисати изузетак, неће доћи до враћања и у табели ће остати четири реда са вредностима 1, нулл, 2 и поново нула.

Који парови вредности ће заузети исту количину простора у блоку?

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, 'Д', 'Вася');

  • А и Х
  • Б и И
  • Ц и К
  • Ц и З
  • К и З
  • Ја и Ј
  • Ј и Кс
  • Сви наведени

ОдговорЕво извода из документације (12.1.0.2) о чувању различитих типова података у Орацле-у.

ЦХАР Тип података
Тип података ЦХАР специфицира низ знакова фиксне дужине у скупу знакова базе података. Ви одређујете скуп знакова базе података када креирате своју базу података. Орацле обезбеђује да све вредности ускладиштене у колони ЦХАР имају дужину наведену величином у семантици изабране дужине. Ако унесете вредност која је краћа од дужине колоне, онда Орацле празни вредност у дужину колоне.

ВАРЦХАР2 Тип података
Тип података ВАРЦХАР2 специфицира низ знакова променљиве дужине у скупу знакова базе података. Ви одређујете скуп знакова базе података када креирате своју базу података. Орацле складишти вредност знакова у ВАРЦХАР2 колони тачно онако како је ви наведете, без икаквих празних поља, под условом да вредност не прелази дужину колоне.

НУМБЕР Тип података
Тип података НУМБЕР складишти нулу, као и позитивне и негативне фиксне бројеве са апсолутним вредностима од 1.0 к 10-130 до, али не укључујући 1.0 к 10126. Ако наведете аритметички израз чија вредност има апсолутну вредност већу или једнаку 1.0 к 10126, онда Орацле враћа грешку. Свака вредност НУМБЕР захтева од 1 до 22 бајта. Узимајући ово у обзир, величина колоне у бајтовима за одређену нумеричку вредност података БРОЈ(п), где је п прецизност дате вредности, може се израчунати коришћењем следеће формуле: ОКРУГЛО((дужина(п)+с)/2))+1 где је с једнако нули ако је број позитиван, а с једнако 1 ако је број негативан.

Поред тога, узмимо извод из документације о чувању Нулл вредности.

Нулл је одсуство вредности у колони. Нуле означавају податке који недостају, непознати или неприменљиви. Нулл се чувају у бази података ако падају између колона са вредностима података. У овим случајевима им је потребан 1 бајт за чување дужине колоне (нула). Завршне нуле у реду не захтевају складиштење јер ново заглавље реда сигнализира да су преостале колоне у претходном реду нулте. На пример, ако су последње три колоне табеле нулте, тада се подаци за ове колоне не чувају.

На основу ових података градимо резоновање. Претпостављамо да база података користи АЛ32УТФ8 кодирање. У овом кодирању руска слова ће заузимати 2 бајта.

1) А и Кс, вредност поља а 'И' заузима 1 бајт, вредност поља к 'Д' заузима 2 бајта
2) Б и И, 'Васиа' у б вредност ће бити допуњена размацима до 10 карактера и заузимаће 14 бајтова, 'Васиа' у д ће заузети 8 бајтова.
3) Ц и К. Оба поља имају вредност НУЛЛ, иза њих су значајна поља, тако да заузимају 1 бајт.
4) Ц и З. Оба поља имају вредност НУЛЛ, али поље З је последње у табели, тако да не заузима простор (0 бајтова). Поље Ц заузима 1 бајт.
5) К и З. Слично као у претходном случају. Вредност у пољу К заузима 1 бајт, у З – 0.
6) И и Ј. Према документацији, обе вредности ће заузети 2 бајта. Израчунавамо дужину користећи формулу преузету из документације: роунд( (1 + 0)/2) +1 = 1 + 1 = 2.
7) Ј и Кс. Вредност у пољу Ј ће заузети 2 бајта, вредност у пољу Кс ће заузети 2 бајта.

Укупно, исправне опције су: Ц и К, И и Ј, Ј и Кс.

Колики ће приближно бити фактор груписања Т_И индекса?

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

  • О десетинама
  • О стотинама
  • Око хиљада
  • Око десетина хиљада

ОдговорПрема Орацле документацији (цитирано од 12.1):

За индекс Б-стабла, фактор груписања индекса мери физичко груписање редова у односу на вредност индекса.

Фактор груписања индекса помаже оптимизатору да одлучи да ли је скенирање индекса или скенирање целе табеле ефикасније за одређене упите). Низак фактор груписања указује на ефикасно скенирање индекса.

Фактор груписања који је близак броју блокова у табели указује на то да су редови физички поређани у блоковима табеле помоћу индексног кључа. Ако база података изврши потпуно скенирање табеле, онда база података тежи да преузме редове онако како су ускладиштени на диску сортирани по индексном кључу. Фактор груписања који је близак броју редова указује на то да су редови насумично распоређени по блоковима базе података у односу на индексни кључ. Ако база података изврши потпуно скенирање табеле, онда база података неће преузимати редове у било ком сортираном редоследу према овом кључу индекса.

У овом случају, подаци су идеално сортирани, тако да ће фактор груписања бити једнак или близу броју заузетих блокова у табели. За стандардну величину блока од 8 килобајта, можете очекивати да ће око хиљаду вредности уских бројева стати у један блок, тако да ће број блокова, а као резултат, бити фактор груписања о десетинама.

При којим вредностима Н ће се следећа скрипта успешно извршити у редовној бази података са стандардним подешавањима?

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

ОдговорПрема Орацле документацији (цитирано од 11.2):

Ограничења логичке базе података

Тачка
Врста ограничења
Лимит Валуе

Индекси
Укупна величина индексиране колоне
75% величине блока базе података минус неки додатни трошкови

Дакле, укупна величина индексираних колона не би требало да прелази 6Кб. Шта се даље дешава зависи од изабраног основног кодирања. За АЛ32УТФ8 кодирање, један знак може заузети највише 4 бајта, тако да ће у најгорем случају 6 килобајта стати око 1500 карактера. Стога, Орацле ће забранити креирање индекса на Н = 400 (када је дужина кључа у најгорем случају 1600 карактера * 4 бајта + дужина низа), док на Н = 200 (или мање) креирање индекса ће радити без проблема.

Оператор ИНСЕРТ са наговештајем АППЕНД је дизајниран за учитавање података у директном режиму. Шта се дешава ако се примени на сто на коме виси окидач?

  • Подаци ће бити учитани у директном режиму, окидач ће радити како се очекује
  • Подаци ће бити учитани у директном режиму, али окидач неће бити извршен
  • Подаци ће бити учитани у конвенционалном режиму, окидач ће радити како треба
  • Подаци ће бити учитани у конвенционалном режиму, али окидач неће бити извршен
  • Подаци се неће учитати, грешка ће бити забележена

ОдговорУ суштини, ово је више питање логике. Да бих нашао тачан одговор, предложио бих следећи модел резоновања:

  1. Убацивање у директном режиму се врши директним формирањем блока података, заобилазећи СКЛ машину, што обезбеђује велику брзину. Дакле, обезбеђивање извршења окидача је веома тешко, ако не и немогуће, и нема смисла у томе, јер ће ипак радикално успорити уметање.
  2. Неизвршавање окидача ће довести до тога да ће, ако су подаци у табели исти, стање базе података у целини (остале табеле) зависити од начина на који су ови подаци уметнути. Ово ће очигледно уништити интегритет података и не може се применити као решење у производњи.
  3. Немогућност извршења тражене операције се генерално третира као грешка. Али овде треба имати на уму да је АППЕНД наговештај, а општа логика наговештаја је да се они узимају у обзир ако је могуће, али ако не, оператор се извршава без узимања у обзир наговештаја.

Дакле, очекивани одговор је подаци ће бити учитани у нормалном (СКЛ) режиму, окидач ће се покренути.

Према Орацле документацији (цитирано од 8.04):

Кршења ограничења ће узроковати да се наредба извршава серијски, користећи уобичајену путању за уметање, без упозорења или порука о грешци. Изузетак је ограничење да изрази приступају истој табели више пута у трансакцији, што може изазвати поруке о грешци.
На пример, ако су окидачи или референтни интегритет присутни у табели, онда ће наговештај АППЕНД бити занемарен када покушате да користите ИНСЕРТ са директним учитавањем (серијски или паралелни), као и наговештај или клаузула ПАРАЛЛЕЛ, ако их има.

Шта ће се догодити када се изврши следећа скрипта?

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

  • Успешно извршење
  • Грешка због синтаксичке грешке
  • Грешка: Аутономна трансакција није важећа
  • Грешка у вези са прекорачењем максималног угнежђења позива
  • Грешка кршења страног кључа
  • Грешка у вези са бравама

ОдговорТабела и окидач су направљени сасвим коректно и ова операција не би требало да доведе до проблема. Аутономне трансакције у окидачу су такође дозвољене, иначе евидентирање не би било могуће, на пример.

Након уметања првог реда, успешно активирање окидача довело би до уметања другог реда, што би изазвало поновно покретање окидача, уметање трећег реда и тако даље све док изјава није успела због прекорачења максималног угнежђења позива. Међутим, још једна суптилна тачка долази у обзир. У време када се окидач изврши, урезивање још није завршено за први уметнути запис. Стога, окидач који ради у аутономној трансакцији покушава да убаци у табелу ред који упућује на страни кључ на запис који још није урезан. Ово резултира чекањем (аутономна трансакција чека да се главна трансакција обавеже да би видела да ли може да убаци податке) и у исто време главна трансакција чека да аутономна трансакција настави са радом након окидача. Долази до застоја и, као резултат тога, аутономна трансакција се отказује због разлога везаних за закључавање.

Само регистровани корисници могу учествовати у анкети. Пријавите се, Добродошао си.

Било је тешко?

  • Као два прста, одмах сам одлучио све како треба.

  • Не баш, погрешио сам у неколико питања.

  • Половину сам тачно решио.

  • Двапут сам погодио одговор!

  • Писаћу у коментарима

Гласало је 14 корисника. Уздржано је било 10 корисника.

Извор: ввв.хабр.цом

Додај коментар