» »

SQL uganka

SQL uganka

MrStein ::

da ne boste samo HotBurek-a brali....
-- setup
create table test (a number, b number , c number /* primary key */ );

-- tole napolni tabelo s podatki za test, z 500000 vrsticami (OK, ena manj)
insert into test select 0,0,level from dual connect by level<500000;
update test set b=99 where mod(c , 2)  = 0; -- tole bi lahko v zgornji INSERT stlačili...



Podatki so torej:


         A          B     C
---------- ---------- ----------
         0          0     1
         0         99     2
         0          0     3
         0         99     4
         0          0     5
         0         99     6
itd...


ukaz 1
update test set a=1 where b=0;

ukaz 2
update test set a=1 where c in (select c from test where b=0);


Vprašanje: a sta zadnja dva UPDATE ukaza enakovredna?

(gre za bazo Oracle, drugi se morebiti drugače obnašajo)

stolpec c je lahko PRIMARY KEY ali pa ne, ne vpliva na tale primer
Motiti se je človeško.
Motiti se pogosto je neumno.
Vztrajati pri zmoti je... oh, pozdravljen!
  • spremenil: MrStein ()

MrStein ::

Dodatno vprašanje:

Če se po kreiranju tabel in podatkov za spremembe uporabljata samo omenjena dva UPDATE ukaza, kake so možne vrednosti (kombinacije) stolpcev a in b ?
Motiti se je človeško.
Motiti se pogosto je neumno.
Vztrajati pri zmoti je... oh, pozdravljen!

Zgodovina sprememb…

  • spremenil: MrStein ()

David Mayer ::

z unikatnim pk c sta enakovredna
a je 1, kjer je b 0

Utisevalec ::

Povedat moraš tudi frekvenco in zaporedje ukazov. Zgornja dva ukaza niti priblizno nista ista v izvedenem zaporedju, sta pa drugače tehnično enaka. SQL baza izvaja ukaze v zaporedju "desno na levo" oz. lahko tudi obratno če daš to funkcijo.

MrStein ::

Utisevalec je izjavil:

Povedat moraš tudi frekvenco in zaporedje ukazov.

Ni specificirano.

Torej poljubno.

Oziroma: kakor pač uporabniki klikajo ;)

Utisevalec je izjavil:

Zgornja dva ukaza niti priblizno nista ista v izvedenem zaporedju


Primer ni podan kot "izvedi 1 potem pa 2" ampak:

Lahko izvedeš enega, ali drugega. A je rezultat v obeh primerih enak?
Motiti se je človeško.
Motiti se pogosto je neumno.
Vztrajati pri zmoti je... oh, pozdravljen!

Zgodovina sprememb…

  • spremenil: MrStein ()

Utisevalec ::

Če smatraš SQL bazo kot transakcijsko, potem ukaza nista enaka, ker se tisti SELECT vedno izvede prej (vmes imaš lahko nafilanih 100 vrstic kjer B == 0 in jih ne bo zajetih v SELECT stavku, bi pa bile v prvem primeru). Če govorimo o 10 updejtih na uro sta pa stavka enaka.

MrStein ::

Ja. Pa tudi če ni novih z b=0, je problem.

Recimo če ... admin* ... izvede:

update test set a=2, b=2 where c between 300000 and 400000;


Potem se lahko v bazi pojavijo zapisi, kjer je:

         A          B
---------- ----------
         1          2


* ker sem prej rekel, da v aplikaciji drugih UPDATE ukazov, razen omenjenih, ni
Motiti se je človeško.
Motiti se pogosto je neumno.
Vztrajati pri zmoti je... oh, pozdravljen!

Utisevalec ::

Kot sem rekel, v transakcijski DB je pomembno zaporedje ukazov. SQL bo desni ukaz vedno izvajal pred levim (SELECT pred INSERT). A izvede admin nek ukaz prej ali pa se izvedejo zapisi vmes je enako. Sicer klasičen catch22 pri teh SQL ukazih imaš v izvajanju linearne kode, kjer hitro dobiš real-life bug (vzemi neko JS "ajax" kodo pa jo izvajaj po koncetu nesinhronosti pa dobiš to kar rabiš za bug).

Zgodovina sprememb…

Zimonem ::

Utisevalec je izjavil:

Kot sem rekel, v transakcijski DB je pomembno zaporedje ukazov. SQL bo desni ukaz vedno izvajal pred levim (SELECT pred INSERT). A izvede admin nek ukaz prej ali pa se izvedejo zapisi vmes je enako. Sicer klasičen catch22 pri teh SQL ukazih imaš v izvajanju linearne kode, kjer hitro dobiš real-life bug (vzemi neko JS "ajax" kodo pa jo izvajaj po koncetu nesinhronosti pa dobiš to kar rabiš za bug).

Kaj pa vem če je primerljivo. Asinhromi klici vseeno niso acid.

David Mayer ::

mislim, da je izraz, ki ga iščete, izolacijski nivo

Zimonem ::

Ja če je c unikat. Sicer ne dam roke v ogenj.

David Mayer ::

To je izhodišče -
c number /* primary key */

Predpostavimo, da op zna vprašati in ni potrebno zahtevati celotnega ddl, če so že neki sekundarni updati postavili...
Brez poznavanja konteksta je težko vedeti, pa še takrat...

(Zelo na daleč) podobno tistemu zaporedju najbolj pogosto rabljenih velikosti chrome-vanadiumovih ključev, ki ni hkrati aritmetično.

:))

Zimonem ::

Tako nekako.

Še A in b bi bila lahko po tabeli samo bolean.

Zgodovina sprememb…

  • spremenilo: Zimonem ()

David Mayer ::

Menim, da je ta uganka absurdna poenostavitev nekega realnega problema ampak IDK-IDC

Utk ::

Utisevalec je izjavil:

Če smatraš SQL bazo kot transakcijsko, potem ukaza nista enaka, ker se tisti SELECT vedno izvede prej (vmes imaš lahko nafilanih 100 vrstic kjer B == 0 in jih ne bo zajetih v SELECT stavku, bi pa bile v prvem primeru). Če govorimo o 10 updejtih na uro sta pa stavka enaka.

No, ampak če gledamo v nekem trenutku, takrat sta enaka, in update bo v drugem primeru naredil isto kot v prvem. Sej ne more nova transakcija, ki prileti vmes, vplivat na updejt, ki se že izvaja, ali?

Zgodovina sprememb…

  • spremenil: Utk ()

MrStein ::

Lahko.
Motiti se je človeško.
Motiti se pogosto je neumno.
Vztrajati pri zmoti je... oh, pozdravljen!

MrStein ::

David Mayer je izjavil:

Menim, da je ta uganka absurdna poenostavitev nekega realnega problema ampak IDK-IDC

Vsaka uganka se prej ali slej pojavi v produkciji...
Motiti se je človeško.
Motiti se pogosto je neumno.
Vztrajati pri zmoti je... oh, pozdravljen!

David Mayer ::

MrStein je izjavil:

Vsaka uganka se prej ali slej pojavi v produkciji...

Tjah... Neke extremely-high-concurrent-processing sistemi srečujejo druge probleme kot preprosta single-user-crud-app in marsikdo se niti ne zaveda težav, ki bi jih moral reševati. Tudi transakcijski izolacijski nivoji se nekoliko razlikujejo že med najbolj znanimi rdbms. Ampak pustimo za kdaj drugič...
:))

Zgodovina sprememb…

MrStein ::

MrStein je izjavil:

Dodatno vprašanje:

Če se po kreiranju tabel in podatkov za spremembe uporabljata samo omenjena dva UPDATE ukaza, kake so možne vrednosti (kombinacije) stolpcev a in b ?


Tole je malo pomanjkljivo. Dodatno velja:
- izhodiščni podatki so kot navedeni v prvem sporočilu
- kličeta se omenjena UPDATE stavka
- ter še tale: update test set a=2, b=2 where c between 300000 and 400000;

Klici so v "naključnem zaporedju" in predvsem "naključna istočasnost".
Motiti se je človeško.
Motiti se pogosto je neumno.
Vztrajati pri zmoti je... oh, pozdravljen!

Zimonem ::

Očitno je na štajerskem trgatev uspela in se po diskontnih ceni praznijo lanske zaloge vina.
Lani vdor na fakulteti letos pa takšnele beremo. Ali ast povsem podrti.

Nobene naključne istočasnosti ni. Preprosto pusti podatkovne baze ker pri teh letih ne razmuš osnovnih konceptov.

Saj ne vem ali sta z matosevim soseda. Je krivo vino ali svinčena vodovodna instalacija?

c3p0 ::

Obstaja tudi ukaz EXPLAIN, ki razloži query plan, no odvisno od baze. Včasih moraš planerja nudgat v pravo smer, ker se sam ne znajde najboljše - kjer EXPLAIN spet zna pomagat.

Definitivno pa je dodaten subquery bolj potraten. Ampak tu smo že pri optimizaciji.

mn ::

MrStein je izjavil:

MrStein je izjavil:

Dodatno vprašanje:

Če se po kreiranju tabel in podatkov za spremembe uporabljata samo omenjena dva UPDATE ukaza, kake so možne vrednosti (kombinacije) stolpcev a in b ?


Tole je malo pomanjkljivo. Dodatno velja:
- izhodiščni podatki so kot navedeni v prvem sporočilu
- kličeta se omenjena UPDATE stavka
- ter še tale: update test set a=2, b=2 where c between 300000 and 400000;

Klici so v "naključnem zaporedju" in predvsem "naključna istočasnost".


Za Oracle sem prepričan in skoraj sigurno velja tudi za vse ostale relacijske baze enako je, da vsak ukaz ki ga poženeš se izvaja v svoji transakciji in tisti UPDATE ... WHERE c IN (SELECT c ...) je en ukaz.

Torej tudi če ta UPDATE in administratorjev UPDATE prideta na bazo istočasno bo eden čakal da se drugi izvede do konca ker morata zaklepati enake bloke in tudi če bo baza res vzporedno izvajala oba dva, bo morala spremembe enega procesa zavreči (ne vem o delovanju dovolj da bi si upal trditi da sploh lahko delata istočasno na obeh).

Pri branju se pa lahko izogneš čakanju da se bloki odklenejo recimo z:

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED - MSSQL server, sigurno imajo tudi druge baze ekvivalent.

Čerav pri Oraclu je to rešeno tako, da ti v resnici za branje vidiš zadnji COMMITED state baze.

EDIT: načeloma si lahko za vsak klic predtavljaš kot da bi ga zapakiral v BEGIN TRANSACTION in END TRANSACTION. Baza to naredi zate avtomatsko.

MrStein je izjavil:

Ja. Pa tudi če ni novih z b=0, je problem.

Recimo če ... admin* ... izvede:

update test set a=2, b=2 where c between 300000 and 400000;


Potem se lahko v bazi pojavijo zapisi, kjer je:

 A B
---------- ----------
1 2


* ker sem prej rekel, da v aplikaciji drugih UPDATE ukazov, razen omenjenih, ni


Oziroma bolj enostavno, če nisem kaj spregledal do tega NE MORE priti.

Zgodovina sprememb…

  • spremenilo: mn ()

Zimonem ::

Tako nekako to je Point acid. Lahko pa je sam server tudi skonfiguriran drugače. Ampak to je potem spet uganka ključevnza šraufe.

David Mayer ::

Če nafutrate AI s to temo na strukturiran način, izpelje precej zanimivie ugotovitve in tudi razloži, čemu.

A damo še kakšne politične teme v celoti ali od kakšnega mejnika, če je ogromno strani? Rezultate pričakujte v... kakšnih treh minutah največ...

Zna biti, da bi marsikakšni slovenski družbeno-intelektualni stereotipi bili ovrženi
:\

MrStein ::

mn je izjavil:


Torej tudi če ta UPDATE in administratorjev UPDATE prideta na bazo istočasno bo eden čakal da se drugi izvede do konca ker morata zaklepati enake bloke in tudi če bo baza res vzporedno izvajala oba dva, bo morala spremembe enega procesa zavreči (ne vem o delovanju dovolj da bi si upal trditi da sploh lahko delata istočasno na obeh).

khm...

(spremembe zavrže izključno ob ROLLBACK - no , razen bugov in eksplodirajočih serverjev...)

mn je izjavil:


Potem se lahko v bazi pojavijo zapisi, kjer je:

 A B
---------- ----------
1 2



Oziroma bolj enostavno, če nisem kaj spregledal do tega NE MORE priti.


Poanta je ravno v tem, da lahko. Če uporabi oni "manj varni" ukaz 2 (z IN ... SELECT ) istočasno z onim ukazom "admina".


Mimogrede: Oracle ima on-line bazo, kjer lahko preverite delovanje: https://livesql.oracle.com/

Ne vem sicer, če omogoča paralelno izvajanje ukazov.
Motiti se je človeško.
Motiti se pogosto je neumno.
Vztrajati pri zmoti je... oh, pozdravljen!


Vredno ogleda ...

TemaSporočilaOglediZadnje sporočilo
TemaSporočilaOglediZadnje sporočilo
»

[MariaDB] SQL WHERE challange: Izpis sprememb cen, vključno z zadnjim vnosom?

Oddelek: Programiranje
6763 (556) HotBurek
»

AMD FX - realnih 8 jeder za vzporedno računanje?

Oddelek: Strojna oprema
343108 (2073) pegasus
»

ali imam quad q9300?

Oddelek: Strojna oprema
122079 (1708) gendale
»

Athlon II X3 425 2.7GHz @ Phenom II X4 3,3GHz

Oddelek: Navijanje
191792 (1375) ferdo
»

Pokvarjen WD Black Edition 1TB?

Oddelek: Strojna oprema
141587 (1211) Deflector

Več podobnih tem