Podzapytania, widoki, indeksy i transakcje

INF.03 · teoria
autor: redakcja · 07.09.2026 · aktualizacja: 08.09.2026
Zapytanie w zapytaniu i pułapka NOT IN z NULL, widok jako zapisane zapytanie, indeks przyspieszający wyszukiwanie kosztem zapisu oraz transakcja z COMMIT i ROLLBACK. Lekcja 8.7 kursu INF.03.
Cztery na­rzę­dzia, które od­róż­nia­ją za­py­ta­nie na­pi­sa­ne „na pie­cho­tę" od za­py­ta­nia na­pi­sa­ne­go świa­do­mie. Po­dza­py­ta­nie wsta­wia wynik jed­ne­go za­py­ta­nia do dru­gie­go, widok za­pa­mię­tu­je za­py­ta­nie pod nazwą, indeks przy­spie­sza wy­szu­ki­wa­nie, a trans­ak­cja pil­nu­je, żeby kilka zmian albo weszło w ca­ło­ści, albo wcale. Na eg­za­mi­nie pi­sem­nym każde z nich ma swój typ py­ta­nia, a naj­częst­sze do­ty­czy in­dek­su: co przy­spie­sza, a co spo­wal­nia.

Tabele do przy­kła­dów

Tabela klient:
id
imie
miasto
1
Anna
Kraków
2
Piotr
Gdańsk
3
Ewa
Kraków
Tabela zamowienie (bez kolumn produkt_id i ilosc, któ­rych ta lekcja nie używa):
id
klient_id
kwota
10
1
650
11
1
120
12
2
25
13
NULL
45

Po­dza­py­ta­nie: za­py­ta­nie w za­py­ta­niu

Po­dza­py­ta­nie to SELECT za­mknię­ty w na­wia­sie, któ­re­go wynik zo­sta­je użyty przez za­py­ta­nie ze­wnętrz­ne. Wy­ko­nu­je się jako pierw­sze.
Jedna war­tość. Po­dza­py­ta­nie zwraca jedną liczbę, więc można ją po­rów­nać przez = albo >:
SELECT nazwa, cena FROM produkt WHERE cena > (SELECT AVG(cena) FROM produkt);
Baza liczy naj­pierw śred­nią (366), potem wy­bie­ra pro­duk­ty droż­sze. Tak za­pi­su­je się py­ta­nie „droż­sze niż śred­nia", któ­re­go nie da się roz­wią­zać jednym WHERE, bo WHERE cena > AVG(cena) jest nie­do­zwo­lo­ne.
Lista war­to­ści. Po­dza­py­ta­nie zwraca ko­lum­nę, więc po­rów­nu­je się przez IN:
SELECT imie FROM klient WHERE id IN (SELECT klient_id FROM zamowienie);
Wynik: Anna, Piotr. To samo py­ta­nie można zadać złą­cze­niem, a IN bywa czy­tel­niej­sze, gdy z dru­giej tabeli nie po­trze­bu­jesz żadnej ko­lum­ny.
Pu­łap­ka: NOT IN prze­sta­je dzia­łać, gdy w po­dza­py­ta­niu pojawi się NULL. WHERE id NOT IN (SELECT klient_id FROM zamowienie) zwraca PUSTY wynik, bo w ko­lum­nie klient_id jest NULL, a po­rów­na­nie z nie­zna­ną war­to­ścią nigdy nie jest praw­dzi­we. Ra­tu­nek: WHERE klient_id IS NOT NULL w po­dza­py­ta­niu albo LEFT JOIN ... WHERE ... IS NULL.
Po­dza­py­ta­nie w FROM. Wynik po­dza­py­ta­nia działa jak tym­cza­so­wa tabela i musi dostać alias:
SELECT AVG(suma) AS srednie_zamowienie FROM (SELECT klient_id, SUM(kwota) AS suma FROM zamowienie GROUP BY klient_id) AS podsumowanie;
Po­dza­py­ta­nie może też stać w SELECT, jako do­dat­ko­wa ko­lum­na wy­li­cza­na dla każ­de­go wier­sza. Taki zapis nazywa się po­dza­py­ta­niem sko­re­lo­wa­nym, bo od­wo­łu­je się do wier­sza z za­py­ta­nia ze­wnętrz­ne­go, i jest wolny przy dużych ta­be­lach.
W prze­glą­dar­ce usuń z po­dza­py­ta­nia wa­ru­nek IS NOT NULL i wy­ko­naj za­py­ta­nie po­now­nie: wynik zrobi się pusty.
[ SQL ]
baza: sklep
zapytanie
103/4000
Otwórz w placu zabaw ›

Widok: za­pi­sa­ne za­py­ta­nie

Widok (VIEW) to za­py­ta­nie za­pa­mię­ta­ne pod nazwą. Za­cho­wu­je się jak tabela, ale nie prze­cho­wu­je danych: przy każdym użyciu wy­ko­nu­je się za­py­ta­nie, z któ­re­go po­wstał.
CREATE VIEW zamowienia_klientow AS SELECT k.imie, k.miasto, z.kwota FROM klient k INNER JOIN zamowienie z ON z.klient_id = k.id; SELECT * FROM zamowienia_klientow WHERE miasto = 'Kraków'; DROP VIEW zamowienia_klientow;
Po co widok:
  • Skraca po­wta­rza­ne za­py­ta­nie. Za­miast pisać złą­cze­nie trzech tabel w dzie­się­ciu miej­scach, pi­szesz je raz.
  • Ogra­ni­cza dostęp. Użyt­kow­ni­ko­wi można nadać prawo do widoku, a nie do tabeli, i wtedy zo­ba­czy tylko wy­bra­ne ko­lum­ny. Na przy­kład listę pra­cow­ni­ków bez ko­lum­ny z pensją.
  • Ukrywa zło­żo­ność. Kto ko­rzy­sta z widoku, nie musi wie­dzieć, z ilu tabel po­wstał.
Widok jest zawsze ak­tu­al­ny, bo dane po­bie­ra z tabel w mo­men­cie użycia. Zmiana danych przez widok jest moż­li­wa tylko w pro­stych przy­pad­kach (jedna tabela, bez gru­po­wa­nia).

Indeks: szyb­ciej czytać, wol­niej pisać

Indeks to do­dat­ko­wa struk­tu­ra, w której baza trzyma po­sor­to­wa­ne war­to­ści ko­lum­ny razem ze wska­za­niem na wiersz. Działa jak sko­ro­widz w książ­ce: za­miast czytać wszyst­kie strony, za­glą­dasz do spisu i idziesz na wła­ści­wą.
CREATE INDEX idx_nazwa ON produkt (nazwa); DROP INDEX idx_nazwa ON produkt;
Co robi indeks
Skutek
przy­spie­sza WHERE, ORDER BY i złą­cze­nia na in­dek­so­wa­nej ko­lum­nie
krót­szy czas wy­szu­ki­wa­nia
spo­wal­nia INSERT, UPDATE i DELETE
przy każdym za­pi­sie trzeba zak­tu­ali­zo­wać także indeks
zaj­mu­je miej­sce na dysku
im więcej in­dek­sów, tym więk­sza baza
Stąd zasada: in­dek­su­je się ko­lum­ny, po któ­rych często SZUKASZ, a nie wszyst­kie. Klucz główny i ko­lum­na UNIQUE do­sta­ją indeks au­to­ma­tycz­nie, więc nie trzeba go two­rzyć ręcz­nie. Klucz obcy w InnoDB także.
Pu­łap­ka: py­ta­nie brzmi zwykle „co przy­spie­sza wy­szu­ki­wa­nie danych, ale może spo­wol­nić ope­ra­cje zapisu". Od­po­wiedź to indeks, nie widok. Widok ni­cze­go nie przy­spie­sza, bo to tylko za­pi­sa­ne za­py­ta­nie.

Trans­ak­cja: wszyst­ko albo nic

Trans­ak­cja łączy kilka po­le­ceń w jedną całość. Albo wy­ko­na­ją się wszyst­kie, albo żadne. Kla­sycz­ny przy­kład to prze­lew: jeżeli pie­nią­dze znik­nę­ły z jed­ne­go konta, muszą po­ja­wić się na drugim.
START TRANSACTION; UPDATE konto SET saldo = saldo - 100 WHERE id = 1; UPDATE konto SET saldo = saldo + 100 WHERE id = 2; COMMIT; -- zatwierdza obie zmiany naraz
COMMIT (ZATWIERDŹ) za­pi­su­je zmiany na stałe. ROLLBACK (WYCOFAJ) cofa wszyst­ko, co zaszło od START TRANSACTION:
START TRANSACTION; DELETE FROM produkt WHERE kategoria = 'monitory'; ROLLBACK; -- wiersze wracają, jakby nic się nie stało
Cztery cechy trans­ak­cji okre­śla skrót ACID: Atomicity (nie­po­dziel­ność: wszyst­ko albo nic), Consistency (spój­ność: baza przed i po jest po­praw­na), Isolation (izo­la­cja: rów­no­le­głe trans­ak­cje sobie nie prze­szka­dza­ją), Durability (trwa­łość: po COMMIT zmiana prze­trwa awarię).
W MySQL trans­ak­cje ob­słu­gu­je silnik InnoDB, do­myśl­ny od wersji 5.5. Star­szy MyISAM ich nie ob­słu­gu­je i po prostu wy­ko­nu­je każde po­le­ce­nie od razu; to samo do­ty­czy kluczy obcych. Stare py­ta­nia z banku pytają o MyISAM jako silnik do­myśl­ny, co dziś nie jest już prawdą.

Na eg­za­mi­nie

Py­ta­nia pi­sem­ne: „Co przy­spie­sza wy­szu­ki­wa­nie, a spo­wal­nia zapis" (indeks), „Które po­le­ce­nie cofa zmiany w trans­ak­cji" (ROLLBACK), „Czym jest widok" (za­pi­sa­ne za­py­ta­nie, nie kopia danych), ra­chu­nek z po­dza­py­ta­niem, gdzie trzeba naj­pierw po­li­czyć wynik we­wnętrz­ne­go SELECT.
In­for­ma­tor CKE wy­mie­nia po­dza­py­ta­nia wprost przy za­da­niu prak­tycz­nym, ale w ty­po­wym ar­ku­szu cztery kwe­ren­dy da się na­pi­sać bez nich. Po­dza­py­ta­nie przy­da­je się, gdy w opisie po­ja­wia się słowo „naj­droż­szy", „po­wy­żej śred­niej" albo „którzy nie mają żad­ne­go".

Ściąga

Rzecz
Zapis
Za­pa­mię­taj
po­dza­py­ta­nie z jedną war­to­ścią
WHERE cena > (SELECT AVG(cena) FROM produkt)
wy­ko­nu­je się pierw­sze
po­dza­py­ta­nie z listą
WHERE id IN (SELECT klient_id FROM zamowienie)
NOT IN psuje NULL
po­dza­py­ta­nie jako tabela
FROM (SELECT ...) AS alias
alias obo­wiąz­ko­wy
widok
CREATE VIEW nazwa AS SELECT ...
za­pi­sa­ne za­py­ta­nie, zero danych
indeks
CREATE INDEX idx ON tabela (kolumna)
szyb­szy odczyt, wol­niej­szy zapis
trans­ak­cja
START TRANSACTION; ... COMMIT;
ROLLBACK cofa całość
ACID
nie­po­dziel­ność, spój­ność, izo­la­cja, trwa­łość
InnoDB tak, MyISAM nie
Pobierz ściągę PDF
ZAWODNIK
egzamin zawodowy INF.02 · INF.03 · INF.04
Serwer Discord
Egzaminy zawodowe IT/Matury/Studia
@yastor
© 2026 Zawodnik · by Yastor
Arkusze i zasady oceniania pochodzą z CKE. Serwis nie jest powiązany z Centralną Komisją Egzaminacyjną.