Podstawy
4 godz. 8 min · Bazy Danych · Full-stack i Programowanie
Pierwszy rozdział wprowadza w historię powstania języka. Wspomnimy o standardach, wykorzystywanych wersjach i podzbiorach SQL’a. Zaraz potem wskoczymy w pierwsze poważne operacje, które pozwolą na pełny cykl tworzenia, zasilania bazy danych i wyciągnięcia z niej wybranych informacji. Rozwikłamy też tajemniczy akronim - CRUD.
Skoro potrafimy już tworzyć bazę i tabele, w które możemy wstawić nowe wiersze, dowiemy się więcej o bardzo ważnej funkcji bazy danych: weryfikacji danych. Zostaną zaprezentowane mechanizmy i techniki, które pomogą utrzymać spójność danych.
W kolejnych lekcjach znajduje się opis serca SQL’a, czyli polecenia wybierającego dane i możliwości i opcji z nim związanych. Od przekształcenia bazy danych w prosty kalkulator, aż do warunków filtrowania wybieranych danych (klauzulą WHERE), sortowania ich (klauzulą ORDER BY), czy ograniczania dużych zestawów wynikowych - w tym wsparcia do paginacji.
SQL jest językiem obsługi relacyjnych baz danych. Dlatego najwyższy czas, aby wspomnieć o relacjach i tym w jaki sposób rozszerzają one możliwości wyszukiwania danych oraz pozwalają zobrazować powiązania między danymi w bazie. Dowiesz się o różnych rodzajach połączeń między tabelami i jak te połączenia (zwane JOIN’ami) pozwalają wybrać to, czego potrzebujesz.
Kolejny rozdział dotyczy grupowania danych (wykorzystując klauzulę GROUP BY) i związanych z tym nowymi możliwościami. Dowiesz się tutaj też w jaki sposób agregować pogrupowane dane i jak takie zagregowane dane filtrować.
Przekonasz się, w jaki sposób można zapamiętywać trudne lub często wykonywane zapytania, wykorzystując do tego widoki (VIEWS) i jak można poprawić wydajność pobierania z nich danych. Przykładowo zastosujemy widoki zmaterializowane (MATERIALISED VIEWS). W tym rozdziale przećwiczysz też możliwość zapisywania danych przez widoki.
Z baz danych korzysta zwykle wielu użytkowników. Aby operacje, które wykonują na wspólnej bazie nie spowodowały nieoczekiwanych konsekwencji, wykorzystuje się mechanizm transakcji. W tym rozdziale wytłumaczymy Ci w jaki sposób użytkownicy mogą modyfikować równolegle te same dane. Tutaj też dowiesz się o poziomach izolacji transakcji i jak używać ich w różnych sytuacjach bazodanowych.
Przy pracy z większą ilością danych, bardzo szybko doświadczysz spowolnienia wykonywania zapytań. O tym jak je przyspieszyć dowiesz się właśnie w tym rozdziale. Zwiększanie wydajności zapytań jest tematem rozległym i zaawansowanym. Tutaj będziesz miał szansę poznać podstawy, w tym - po co są i jak używać indeksów, w jaki sposób analizować jak zapytania są wykonywane i jakie jeszcze są metody wydajniejszego odczytywania danych.
Kurs jest dla osób początkujących, rozpoczynających przygodę z bazami danych. Nie wymaga się znajomości SQL'a ani zaawansowanej wiedzy dotyczącej baz danych. Warto wiedzieć co to są relacyjne bazy danych. Dobrze mieć dostęp do ulubionego silnika bazy danych, ale nie jest to wymagane.
W poprzedniej lekcji sprawdzałeś jak indeks
wpływa na czas wykonania zapytania badając
ten czas przed stworzeniem indeksu i po stworzeniu
indeksu często jednak piszemy zapytania kiedy indeks
już istnieje w jaki sposób w takim razie możemy sprawdzić czy
wykorzystuje ten indeks czy nie w tej lekcji poznasz
narzędzie które pozwoli ci na taką analizę zanim
jednak przejdziemy do przedstawienia tego narzędzia spójrzmy na rozwiązanie
do zadania z poprzedniej lekcji zadanie polegało na przyspieszeniu
zapytania właśnie na stworzeniu indeksu który by przyspieszył
takie zapytanie zapytanie wybierające wszystkie kolumny
z tabeli big data gdzie wartości w kolumnie big number są
pomiędzy zadanymi liczbami zobaczymy jak
szybko uruchamia się to za pytanie w tej chwili trwała ona
dwie sekundy ale jeżeli uruchomimy je jeszcze raz o
to już lepiej 264 milisekundy czyli
jak widać około 200 milisekund
skąd to pierwsze uruchomienie jest dłuższe
niż kolejne dlatego że przy pierwszym uruchomieniu baza
zapamiętuje część danych tego zapytania w takiej specjalnej
pamięci podręcznej i przy kolejnych uruchomienia korzysta z tych
z tych danych wszystkie kolejne oprócz pierwszego są szybsze kiedy chce porównać
czasy zapytań to porównuje te czasy po
scache'owaniu dlatego że mogę je powtórzyć i zobaczyć
właśnie średnia prędkość wykonywania tego zapytania poza tym
ten czas wykonania pierwszego uruchomienia zapytania jest
no można powiedzieć niepowtarzalny albo trudno powtarzalny dlatego
będę się opierał na tych czasach z kolejnych uruchomień a teraz stworzymy
indeks na kolumnie która tutaj jest używana
do ograniczenia danych do warunku r tak wygląda syntax
tworzenia indeksu przedstawiane na poprzedniej lekcji
indeks się stworzył w dwie sekundy i w tej chwili już to zapytanie będzie
trwało proszę bardzo 130 około 100 milisekund
czyli 2 razy szybciej niż bez indeksu pięknie możemy teraz
przejść do głównej części lekcji tym razem wezmę
na warsztat proste zapytanie które wyciąga dane
i ogranicza je na podstawie wartości kolumny
identyfikatora czyli klucza głównego trwa ona
około 800 milisekund ale ona nic nie mówi za bardzo co
się dzieje pod spodem tu warto wiedzieć że wykonanie zapytania składa
się z kilku faz więc pierwsza faza analizy leksykalnej czy
zapytanie nie ma żadnych błędów jest druga faza przygotowania planu
wykonania zapytania przez tak zwany planner który
patrzy na zapytanie patrzy na konfigurację zasoby i
planuje co trzeba zrobić żeby jak najlepiej wykonać to zapytanie
jak najszybciej potem następuje już samo wykonanie zapytania odniesienie
się do do danych bazy jeżeli jest to zapytanie
select to ostatnia faza to jest wyciągnięcie i zwrócenie tych
danych do klienta czyli na przykład tak jak tutaj mamy pg admina
te dane są przekazane do aplikacji która je wyświetla
żeby zobaczyć jak to zapytanie będzie
wykonywane czyli co planer dla nas zaplanował
używa się polecenia explain polecenie explain nie
wykonuje zapytania tylko pokazuje jakie
czynności będą wykonywane w ramach uruchamiania tego zapytania
tutaj jest wynik tego
explaina tylko dwie linijki natomiast o co
tu chodzi seq scan oznacza nic innego jak sequential
scan sequential scan znaczy tyle że cała tabela
big data będzie przeglądana w poszukiwaniu rekordów
które spełniają ten warunek czyli pobrane dane będą
filtrowane przez ten warunek i zwracamy tak generalnie
to oznacza od dużo odczytów z dysku
w poszukiwaniu tych danych które które chcemy nic
tutaj o żadnych indeksach nie ma no tak ale
przecież jest indeks na kolumnie id prawda możemy zresztą
sprawdzić tutaj o proszę bardzo jest klucz główny a
wiadomo że na kluczu głównym zawsze jest założony indeks
spróbuję teraz zmniejszyć to ograniczenie tak żeby wybierać
tylko rekordy może nie większe a mniejsze od
1000 jest tam sporo ograniczeń zbiór danych który chcemy
zwrócić i uruchamiam teraz tego explaina i proszę
bardzo tym razem pięknie się nam pokazał index
scan to znaczy że używając indeksu big data pkey na kluczu
głównym wyciągane są te adresy rekordu który chcę pobrać
i dla takiego warunku tak z indeksu są wybierane adresy
rekordów które chcemy pobrać i baza tylko z tych rekordów odczytuje
dane stąd to przyspieszenie tak bo nie ma skanu całej tabeli tylko
wybieramy część danych dlaczego to
tak wyglądało że przy dużej ilości danych indeks nie był użyty dlatego
że planner wie że nawet jeżeliby by użył indeksu przy zapytaniu
które zwraca dużą ilość danych z tablicy i tak musiałby
odczytywać te wszystkie dane z dysku bo koniec końców chcemy pobrać
te wszystkie dane więc po prostu nie opłaca się jeszcze sięgać
do indeksu wczytywać ten indeks do pamięci i szukać w nim bo
koszt byłby bardzo podobny znaczy nie przyspieszyłoby to
znacząco pobierania danych na wydajność
działania indeksów wpływa też to jakie dane trzymane są
w kolumnie jeżeli chodzi o kolumnę identyfikatora na przykład
tam są dane unikalne to znaczy każdy każda
wartość przyporządkowana jest do pojedynczego rekordu
na dysku dlatego planner mógł spokojnie odwołać
się do indeksu i dokładnie wybrać te rekordy które
wynikły z przejrzenia indeksu inaczej ma się jeżeli
w kolumnie mogą być wartości zdublowane wtedy jest tak
że dla pojedynczej wartości możemy mieć kilka
rekordów które jej odpowiadają tak i wtedy już scan index
zwróci nam zestaw rekordów niekoniecznie uporządkowany
w przypadku wyciągania danych w przypadku wyciągania
danych z kolumny identyfikatora jeżeli wybierzemy dane które są
mniejsze niż 1000 no to index nam da po kolei wszystkie adresy na
dysku natomiast jeżeli mamy wartość jakiejś kolumny która się
powtarza no to dostaniemy kilka różnych niekoniecznie uporządkowanych
tak a po to żeby wydajniej odczytywać z dysku
najlepiej mieć te adresy uporządkowane przyjrzymy się w takim razie zapytaniu
z poprzedniej lekcji to jest to zapytanie i teraz
dorzucimy tutaj explain żeby zobaczyć co nam
powie planner planner nam mówi że oczywiście tak użyję indeksu
ale nie użyję go bezpośrednio tak jak w przypadku zapytania
na kolumnie identyfikatora tylko najpierw zbierz adresy
z indeksu a później je sobie poukładasz że tak powiem
a później dopiero je wykorzystam do agregacji tak ale generalnie informacja
dla nas ważna taka że został użyty indeks to przyspieszy zapytanie
bo w większości przypadków użycia indeksu przyspiesza zapytania natomiast
jest tutaj informacje też że że są tutaj dodatkowe czynności które
muszą być wykonane które kosztują więcej czasu no właśnie jeszcze
komentarz do do tych danych które są tutaj w nawiasach koszt
który tutaj jest wyświetlany to jest koszt w cyklach procesora
który planner zakłada że będzie potrzebny żeby wykonać dane
operacje tak tu jest najpierw ten skan kosztuje to 1600
jednostek tutaj to jest 4000 jednostek i
na końcu już sama agregacja to jest prawie nic i tu przy
okazji też jest informacja na jakim zbiorze danych jakby operacje
są przeprowadzane tu już agregacja jest do jednego wiersza bo to jest tylko wartość
średnia to jest tylko plan tak więc jak to będzie wykonane
ostatecznie tego do końca nie wiadomo zakładamy że mniej
więcej według planu jeżeli chcemy wiedzieć jak to zapytanie zostało
zrealizowane do explaina dodajemy takie słowo kluczowe
analyze jak odpalimy to
zapytanie to dostajemy dodatkowe informacje po pierwsze jaki
był czas planowania jaki czas egzekucji czy wykonania
zapytania ale też oprócz tutaj tych kosztów jest actual time
czyli ostateczny czas wykonania tych operacji tak tutaj jest
ten czas jest w sekundach znaczy w milisekundach ile wierszy jakby
każdy element zwrócił i ile powtórzeń danej operacji było
zrobione bo czasami jest tak że tu jest operacja szybka
i niewiele danych zwraca ale musi obrócić kilkaset tysięcy razy
żeby wszystkie dane przetworzyć i wtedy się okazuje że
jest kosztowna mimo że wydawałoby się że na małej ilości danych działa
o tych danych mówię tak orientacyjnie żebyś wiedział z czym to się je i o
co tutaj chodzi natomiast tak naprawdę w tej chwili najważniejsze jest to i chciałbym
żebyś jakby wyniósł tą wiedzę czy indeks jest wykorzystywany
przez dane zapytanie czy nie na tym poziomie jakby to powinno ci wystarczyć
Rozwiązanie do zadania do przepracowania z poprzedniej lekcji · 2 min
SELECT * FROM big_data WHERE big_number BETWEEN 100000 AND 140000;
CREATE INDEX big_data_big_number_idx ON big_data (big_number);
SELECT * FROM big_data WHERE big_number BETWEEN 100000 AND 140000;Analiza zapytania nieoptymalnego (seq scan) · 4 min
-- operacja pokazująca plan wykonania podanego zapytania
EXPLAIN SELECT * FROM big_data WHERE id > 1000000;Analiza zapytania optymalnego do użycia indeksu · 6 min
-- zapytanie zmieniamy, tak by operowało na mniejszym zbiorze
EXPLAIN SELECT * FROM big_data WHERE id < 1000;
-- w tej chwili dla takiej niewielkiej grupy rekordów opłaca się planerowi użyć indeksu
-- dlatego teraz będzie do skan indeksuAnaliza zapytania optymalnego z agregacją danych · 8 min
-- tym razem sprawdzamy plan wykonania zapytania z agregacją danych
EXPLAIN SELECT avg(random_price) FROM big_data WHERE random_price < 200;
-- ponieważ zbiór danych jest niewielki, to także tutaj jest wykorzystywany indeks
-- natomiast nie w bezpośredni sposób