| Typ | Opis | Przykład |
|---|---|---|
| Proste | Stałe warunki — zwraca zawsze te same wiersze | SELECT * FROM produkty WHERE aktywny = 1 |
| Parametryczne | Parametry wypełniane dynamicznie przez użytkownika | WHERE cena < ? AND kategoria = ? |
| Krzyżowe | Dane pogrupowane wierszami i kolumnami (pivot) | Sprzedaż per miesiąc i per kategoria |
| Podsumowujące | Agregacje — COUNT, SUM, AVG per grupy | Raport: suma sprzedaży per region |
? lub :nazwa). Chroni przed SQL Injection — wartości parametrów są przekazywane oddzielnie od struktury zapytania.
-- PHP PDO — zapytanie parametryczne $stmt = $pdo->prepare( 'SELECT * FROM produkty WHERE cena < ? AND id_kategorii = ?' ); $stmt->execute([$maxCena, $idKat]); $wyniki = $stmt->fetchAll(); -- Z nazwanymi parametrami $stmt = $pdo->prepare( 'SELECT * FROM klienci WHERE email = :email AND aktywny = :aktywny' ); $stmt->execute([':email' => $email, ':aktywny' => 1]); -- MySQL: PREPARE/EXECUTE (po stronie serwera) PREPARE stmt FROM 'SELECT * FROM produkty WHERE cena < ? AND kategoria = ?'; SET @max = 500, @kat = 'Elektronika'; EXECUTE stmt USING @max, @kat; DEALLOCATE PREPARE stmt;
$sql = "SELECT * FROM klienci WHERE email = '$email'";$email = "' OR 1=1; DROP TABLE klienci; --"
-- Raport: sprzedaż per kategoria i miesiąc SELECT k.nazwa AS kategoria, DATE_FORMAT(z.data, '%Y-%m') AS miesiac, COUNT(*) AS liczba_transakcji, SUM(pz.ilosc * pz.cena_jedn) AS przychod FROM kategorie k JOIN produkty p ON k.id_kategorii = p.id_kategorii JOIN pozycje_zamowien pz ON p.id_produktu = pz.id_produktu JOIN zamowienia z ON pz.id_zamowienia = z.id_zamowienia GROUP BY k.nazwa, DATE_FORMAT(z.data, '%Y-%m') ORDER BY miesiac, przychod DESC; -- Top 10 klientów po wartości zamówień SELECT k.imie, k.nazwisko, k.email, COUNT(z.id_zamowienia) AS liczba_zam, SUM(z.kwota) AS laczna_wartosc FROM klienci k INNER JOIN zamowienia z ON k.id_klienta = z.id_klienta GROUP BY k.id_klienta, k.imie, k.nazwisko, k.email ORDER BY laczna_wartosc DESC LIMIT 10;
-- Tworzenie indeksu na często filtrowanej kolumnie CREATE INDEX idx_klienci_email ON klienci(email); CREATE INDEX idx_zamowienia_data ON zamowienia(data); CREATE INDEX idx_produkty_kat_cena ON produkty(kategoria, cena); -- EXPLAIN — analiza planu wykonania zapytania EXPLAIN SELECT * FROM klienci WHERE email = 'jan@mail.com'; -- Kluczowe kolumny w EXPLAIN: -- type: ALL=pełny skan (wolny), ref/eq_ref=indeks (szybki) -- key: użyty indeks (NULL = brak indeksu!) -- rows: szacowana liczba przeglądanych wierszy
| Wartość type | Opis | Wydajność |
|---|---|---|
ALL | Pełny skan tabeli | Najgorsza |
index | Skan całego indeksu | Słaba |
range | Zakres indeksu (BETWEEN, >, <) | Dobra |
ref | Indeks nieunikalny | Dobra |
eq_ref | Indeks unikalny (JOIN) | Bardzo dobra |
const | Klucz główny lub UNIQUE z wartością | Najlepsza |
Do czego służy polecenie EXPLAIN SELECT ...?
Napisz zapytanie zwracające top 10 klientów według łącznej wartości ich zamówień (imię, nazwisko, suma zamówień):
Które stwierdzenie o zapytaniach parametrycznych (prepared statements) jest PRAWDZIWE?
EXPLAIN pokazuje plan zapytania — czy używa indeksów (key), ile skanuje wierszy (rows)