Generator indeksu SQL
Polecenie CREATE INDEX dla MySQL, PostgreSQL i SQLite z kontrolą ograniczeń silnika i gotowym DROP INDEX.
-
1Wprowadź dane
Wpisz treść, wklej tekst lub załaduj plik z dysku. -
2Kliknij przycisk
Narzędzie natychmiast przetworzy Twoje dane w przeglądarce. -
3Pobierz wynik
Skopiuj gotowy tekst lub zapisz plik na urządzeniu.
return "Wynik gotowy w 0.1s";
}
created_at DESC.Polecenie CREATE INDEX
Silnik
Wykryty z użytych opcji. Wybierz silnik ręcznie, jeśli to nie ten.
Rodzaj indeksu
Metoda
Kolumny w kluczu
Długość nazwy
Limit: 63 znaki
Cofnięcie i podgląd indeksów
Ściąga: indeksy w MySQL, PostgreSQL i SQLite
| Funkcja | MySQL (InnoDB) | PostgreSQL | SQLite |
|---|---|---|---|
| UNIQUE | tak | tak (tylko BTREE) | tak |
| Wybór metody (USING) | BTREE, HASH (InnoDB i tak użyje BTREE) | BTREE, HASH, GIN, GIST i inne | brak, zawsze B-drzewo |
| Indeks częściowy (WHERE) | nie | tak | tak |
| INCLUDE (indeks pokrywający) | nie | tak (BTREE; GIST od wersji 12) | nie |
| Kierunek ASC / DESC | tak (DESC działa od wersji 8.0) | tak (tylko BTREE) | tak |
| CONCURRENTLY | nie | tak | nie |
| IF NOT EXISTS | nie (MariaDB: tak) | tak | tak |
| Maks. kolumn w kluczu | 16 | 32 | zależne od limitu kolumn tabeli |
| Metoda | Do czego | Ograniczenia |
|---|---|---|
| BTREE | równość, zakresy (<, >, BETWEEN) i sortowanie ORDER BY | domyślny wybór; obsługuje wszystkie opcje generatora |
| HASH | wyłącznie porównania równości (=) | w PostgreSQL: jedna kolumna, bez UNIQUE i INCLUDE |
| GIN | szukanie wewnątrz wartości złożonych: jsonb, tablice, tsvector | tylko PostgreSQL; bez UNIQUE i INCLUDE |
| GIST | dane geometryczne, zakresy, wyszukiwanie najbliższego sąsiada | tylko PostgreSQL; bez UNIQUE |
Jak zbudowano to polecenie
| Fragment | Co robi |
|---|---|
| CREATE INDEX | tworzy zwykły indeks |
| `idx_orders_user_id_created_at` | nazwa indeksu |
| ON `orders` | tabela, której dotyczy indeks |
| (`user_id`, `created_at`) | kolumny klucza; kolejność ma znaczenie |
| USING BTREE | metoda (struktura) indeksu |
Kolejność kolumn
Indeks (user_id, created_at) przyspiesza zapytania filtrujące po user_id oraz po obu kolumnach naraz. Zapytanie tylko po created_at zwykle nie wykorzysta go skutecznie. Najpierw dawaj kolumny porównywane przez =, na końcu kolumnę z zakresem lub sortowaniem.
Cena indeksu
Indeks przyspiesza odczyt, ale spowalnia INSERT, UPDATE i DELETE oraz zajmuje miejsce na dysku. Nie warto indeksować kolumn z kilkoma wartościami (np. tak/nie), chyba że jako indeks częściowy. Usuwaj indeksy, z których żadne zapytanie nie korzysta.
Czy indeks działa?
Uruchom zapytanie z przedrostkiem EXPLAIN (w SQLite: EXPLAIN QUERY PLAN) i poszukaj w planie nazwy idx_orders_user_id_created_at. Na małej tabeli baza może wybrać pełny odczyt i to jest normalne.
Częściowy i pokrywający
Indeks częściowy (WHERE) obejmuje tylko wybrane wiersze, więc jest mniejszy, ale zapytanie musi zawierać ten sam warunek. INCLUDE dodaje kolumny tylko do odczytu, dzięki czemu zapytanie bywa obsłużone z samego indeksu.
Oceń to narzędzie:
Powiązane narzędzia
Inne narzędzia, które mogą Ci się przydaćGenerator indeksu SQL
Indeks SQL przyspiesza wyszukiwanie kosztem miejsca i wolniejszego zapisu. Dobrze dobrany indeks bywa różnicą między zapytaniem w milisekundach a trwającym sekundy. Generator składa polecenie CREATE INDEX dla MySQL, PostgreSQL lub SQLite, pilnuje ograniczeń wybranego silnika i od razu podaje polecenie cofnięcia (DROP INDEX) oraz zapytanie wyświetlające indeksy tabeli.
Rodzaje indeksów
| Element | Zastosowanie | Silniki |
|---|---|---|
| Złożony | wiele kolumn — kolejność ma znaczenie | MySQL (do 16 kolumn), PostgreSQL (do 32), SQLite |
| UNIQUE | wymusza unikalność wartości | wszystkie; w PostgreSQL tylko z metodą BTREE |
| Częściowy (WHERE) | indeksuje podzbiór wierszy | PostgreSQL, SQLite |
| Pokrywający (INCLUDE) | kolumny dodatkowe bez wpływu na klucz | PostgreSQL (BTREE, GIST) |
Kolejność kolumn
W indeksie złożonym kolumny równościowe (np. user_id) dawaj przed zakresowymi (created_at). Zapytanie musi wykorzystywać prefiks indeksu, aby z niego skorzystać.
Przykład
Indeks na orders (user_id, created_at) przyspieszy zapytanie „zamówienia użytkownika posortowane po dacie”.
Jak działa generator indeksu SQL
Generator zamienia deklarację z formularza na gotową instrukcję DDL. Wybierasz silnik bazy (MySQL, PostgreSQL, SQLite albo tryb automatyczny), podajesz tabelę i kolumny po przecinku w wybranej kolejności, a po nazwie kolumny możesz dopisać ASC lub DESC. W opcjach zaawansowanych ustawiasz nazwę indeksu, metodę (BTREE, HASH, GIN, GIST), kolumny INCLUDE, warunek WHERE oraz przełączniki UNIQUE, IF NOT EXISTS i CONCURRENTLY. Podgląd odświeża się przy każdej zmianie, a sześć gotowych wzorców (złożony, unikalny, częściowy, sortowany, pokrywający, klucz obcy) wypełnia formularz jednym kliknięciem.
Tryb automatyczny generuje składnię MySQL, a na PostgreSQL przełącza się, gdy użyjesz opcji, których MySQL nie ma: GIN, GIST, WHERE, INCLUDE, CONCURRENTLY lub IF NOT EXISTS. Jeśli piszesz pod SQLite, wybierz go ręcznie. Gdy opcja nie pasuje do wybranego silnika, narzędzie zamiast polecenia pokazuje błąd przy polu, np. że MySQL nie obsługuje indeksów częściowych albo że w PostgreSQL indeks HASH obejmuje tylko jedną kolumnę.
Kolejność kolumn w nawiasie to kolejność sortowania w B-drzewie. Kolumna równościowa (np. user_id) zawęża zbiór do jednej wartości, a kolumna zakresowa lub sortowana (np. created_at) porządkuje wynik w obrębie tego zbioru. Odwrotna kolejność zwykle kończy się skanem całej tabeli albo sortowaniem po stronie silnika.
Składnia zależy od silnika. MySQL: CREATE [UNIQUE] INDEX `nazwa` ON `tabela` (kolumny) USING BTREE; — metoda stoi po liście kolumn, a nazwy są w odwrotnych apostrofach. PostgreSQL: CREATE [UNIQUE] INDEX [CONCURRENTLY] [IF NOT EXISTS] "nazwa" ON "tabela" USING metoda (kolumny) [INCLUDE (...)] [WHERE warunek];. SQLite nie pozwala wybrać metody, więc USING się nie pojawia. Jeśli nie podasz nazwy indeksu, narzędzie buduje ją według wzoru idx_tabela_kolumna_kolumna i zgłasza błąd, gdy przekroczy 63 znaki (limit w MySQL i PostgreSQL). Sprawdź też, czy nazwa nie koliduje z istniejącą w bazie.
Przykład krok po kroku
- Dane wejściowe: tabela orders z 2 000 000 wierszy, kolumny user_id (BIGINT), created_at (timestamp), status (text). W bazie jest 50 000 użytkowników. Zapytanie brzmi: SELECT z tabeli orders WHERE user_id = ? ORDER BY created_at DESC LIMIT 20.
- W polu tabeli wpisujesz orders, a w polu kolumn:
user_id, created_at DESC— najpierw kolumna z warunkiem równościowym, potem sortowana. Odwrotna kolejność nie obsłuży tego zapytania, bo created_at nie jest filtrowane. - Zostawiasz metodę BTREE, tryb zwykły i silnik automatyczny. Wynik (składnia MySQL):
CREATE INDEX `idx_orders_user_id_created_at` ON `orders` (`user_id`, `created_at` DESC) USING BTREE;Nazwa ma 29 znaków. Narzędzie dopisuje uwagę, że MySQL przed wersją 8.0 ignoruje DESC w definicji indeksu. - Dodajesz INCLUDE: status, aby silnik mógł odczytać status bez sięgania do tabeli. Ponieważ MySQL nie zna INCLUDE, tryb automatyczny przechodzi na PostgreSQL:
CREATE INDEX "idx_orders_user_id_created_at" ON "orders" USING BTREE ("user_id", "created_at" DESC) INCLUDE ("status");Kolumna w INCLUDE nie zmienia kolejności klucza i nie służy do filtrowania. Przy ręcznie wybranym MySQL zobaczysz błąd z podpowiedzią, by dopisać kolumnę do klucza. - Liczysz zysk: bez indeksu silnik sprawdza 2 000 000 wierszy; z indeksem trafia w gałąź odpowiadającą jednemu user_id, czyli średnio 2 000 000 / 50 000 = 40 wierszy na użytkownika, a z LIMIT 20 odczytuje tylko pierwsze 20.
- Szacujesz koszt miejsca: klucz to 8 B (BIGINT) + 8 B (timestamp) = 16 B na wiersz, czyli 2 000 000 × 16 B = 32 000 000 B ≈ 30,5 MiB samych danych klucza, plus narzut struktury B-drzewa i kolumna status z INCLUDE, których narzędzie nie liczy.
Opcje generatora i ich efekt w DDL
| Opcja | Co trafia do instrukcji | Kiedy stosować |
|---|---|---|
| BTREE | USING BTREE (w MySQL po liście kolumn, w PostgreSQL przed nią, w SQLite pomijane) | Dopasowania równościowe, zakresy i sortowanie — wybór domyślny. |
| HASH | USING HASH | Tylko dopasowania równościowe. W PostgreSQL jedna kolumna; InnoDB w MySQL i tak tworzy BTREE. |
| GIN, GIST | USING GIN / USING GIST (tylko PostgreSQL) | Kolumny jsonb, tablice, tsvector, dane geometryczne i zakresy. |
| UNIQUE | CREATE UNIQUE INDEX | Gdy kolumna lub zestaw kolumn ma wymuszać unikalność wartości. |
| WHERE | Indeks częściowy z warunkiem | Gdy zapytania dotyczą stałego podzbioru wierszy, np. tylko zamówień ze statusem pending. |
| INCLUDE | Lista kolumn dodatkowych po kluczu | Gdy chcesz pokryć zapytanie bez zmiany kolejności i zakresu klucza. |
| DESC / ASC | Kierunek kolumny w kluczu, dopisany po jej nazwie | Gdy ORDER BY w zapytaniu ma stały kierunek sortowania. W PostgreSQL tylko z BTREE. |
| CONCURRENTLY | CREATE INDEX CONCURRENTLY (tylko PostgreSQL) | Duże tabele w produkcji, gdy budowa indeksu nie może blokować zapisów. |
| IF NOT EXISTS | CREATE INDEX IF NOT EXISTS (PostgreSQL, SQLite) | Skrypty migracji uruchamiane wielokrotnie. |
| Indeks złożony | Wiele kolumn w nawiasie, w podanej kolejności | Gdy zapytanie filtruje po kilku kolumnach albo filtruje i sortuje jednocześnie. |
| Nazwa indeksu | Własna nazwa lub wygenerowana z tabeli i kolumn (do 63 znaków) | Dla spójnych konwencji nazewnictwa i czytelnych migracji. |
Praktyczne wskazówki
- Zacznij od zapytań, nie od kolumn. Wypisz wzorce WHERE, JOIN i ORDER BY, które faktycznie chodzą w aplikacji, i pod każdy z nich zaprojektuj osobny indeks. Indeks bez zapytania tylko zajmuje miejsce i spowalnia zapis.
- Nie powielaj prefiksów: indeks na kolumnach (user_id, created_at) obsłuży też zapytania filtrujące wyłącznie po user_id, więc osobny indeks na samym user_id jest zwykle zbędny.
- Ustal jedną konwencję nazw. Schemat typu idx_tabela_kolumna_kolumna ułatwia późniejsze wyszukanie i usunięcie indeksu oraz porównanie środowisk.
- Kolumny potrzebne tylko w SELECT wrzucaj do INCLUDE zamiast dopisywać je do klucza. Nie zmieniają sortowania i nie służą do filtrowania, ale mogą ograniczyć odczyty z tabeli.
- Na dużej tabeli w PostgreSQL włącz CONCURRENTLY. Takie polecenie nie działa wewnątrz transakcji (BEGIN … COMMIT), a gdy budowa się nie powiedzie, zostaje indeks oznaczony jako INVALID, który trzeba usunąć przed ponowną próbą.
Czego narzędzie nie uwzględnia
- Nie łączy się z bazą danych: nie sprawdzi, czy indeks już istnieje, czy nazwa jest wolna ani jakie typy mają kolumny. Przy GIN i GIST tylko ostrzega, że kolumna musi mieć odpowiedni typ (dla zwykłych typów bywa potrzebne rozszerzenie pg_trgm, btree_gin lub btree_gist).
- Nie analizuje planów zapytań, więc nie wie, czy silnik faktycznie użyje wygenerowanego indeksu. To potwierdza dopiero EXPLAIN (MySQL), EXPLAIN ANALYZE (PostgreSQL) lub EXPLAIN QUERY PLAN (SQLite) na realnych danych.
- Nie szacuje rozmiaru ani czasu budowy, bo nie zna liczby wierszy ani statystyk kolumn. Koszt miejsca i czas tworzenia indeksu sprawdzisz tylko po stronie bazy.
- Nie sprawdza składni warunku WHERE — odrzuca jedynie średnik, który oznaczałby drugie polecenie. Nie rozróżnia też wersji silnika: zgłasza ograniczenia MySQL, PostgreSQL i SQLite jako całości, a różnice między wersjami (np. DESC przed MySQL 8.0) podaje tylko jako uwagi.
Najczęstsze pytania
Jak stworzyć indeks w SQL?
Podaj tabelę i kolumny w formularzu, a generator złoży instrukcję w postaci CREATE INDEX nazwa ON tabela (kolumna1, kolumna2) w składni wybranego silnika. Skopiowany tekst uruchamiasz w konsoli swojej bazy.
BTREE czy HASH?
BTREE działa dla równości, zakresów i sortowania — stosuj go domyślnie. HASH obsługuje tylko porównanie „=”, a w MySQL z InnoDB i tak zostanie zamieniony na BTREE.
Jak sprawdzić, czy zapytanie używa indeksu?
Poprzedź zapytanie słowem EXPLAIN (w PostgreSQL najlepiej EXPLAIN ANALYZE, w SQLite EXPLAIN QUERY PLAN) i poszukaj w planie nazwy indeksu. Na małej tabeli silnik może wybrać pełny odczyt i to jest normalne.
Jak usunąć indeks i wyświetlić indeksy tabeli?
W MySQL: DROP INDEX nazwa ON tabela i SHOW INDEX FROM tabela. W PostgreSQL i SQLite: DROP INDEX IF EXISTS nazwa, a listę indeksów dają zapytanie do pg_indexes lub PRAGMA index_list. Generator podaje te polecenia pod wynikiem, już z Twoją nazwą indeksu i tabeli.
Czym różni się indeks UNIQUE od zwykłego?
Indeks UNIQUE wymusza unikalność wartości w kolumnie lub zestawie kolumn i blokuje próby wstawienia duplikatu. Zwykły indeks tylko przyspiesza wyszukiwanie i dopuszcza powtórzone wartości. W indeksie częściowym unikalność dotyczy tylko wierszy spełniających warunek WHERE.
Czy generator wykona indeks na mojej bazie?
Nie. Narzędzie nie łączy się z Twoim serwerem bazy i zwraca wyłącznie tekst DDL. Instrukcję uruchamiasz samodzielnie, najlepiej najpierw na kopii lub środowisku testowym.