Zapisz się na nasz newsletter
Otrzymuj regularne aktualizacje, specjalne oferty i porady od ekspertów, które pomogą Ci osiągnąć więcej w krótszym czasie.
PostgreSQL stawia na zgodność ze standardem, rozszerzalność i precyzję. MySQL — na prostotę, wydajność i łatwość wdrożenia. W praktyce oznacza to zupełnie inny sposób projektowania schematów, indeksów i zapytań.
W tym artykule zobaczysz te różnice bez marketingu i mitów — w oparciu o realne zachowania silników, przykłady SQL i praktyczne zastosowania. Jeśli zastanawiasz się, którego SQL-a warto dziś poznać lub wybrać do projektu, po tej lekturze będziesz wiedzieć dokładnie, dlaczego czasem warto sięgnąć po oba.
Ogólne porównanie architektury
PostgreSQL vs MySQL to przede wszystkim różna filozofia architektury. PostgreSQL to jeden silnik z MVCC opartym o wersjonowanie wierszy (tuple), WAL i proces-per-połączenie. MySQL to serwer z wieloma silnikami magazynowania, ale praktycznie zawsze używany jest InnoDB (MVCC przez undo logi) i model wątek-per-połączenie. W praktyce PostgreSQL wymaga częściej zewnętrznego poolera (np. PgBouncer), a MySQL efektywnie skaluje liczbę wątków w samym serwerze.
W replikacji PostgreSQL oferuje replikację strumieniową (fizyczną) i logiczną na poziomie publikacji/subskrypcji. MySQL ma replikację binlog (asynchroniczną, pół-synchroniczną), a także Group Replication/InnoDB Cluster. Sharding zwykle realizuje się narzędziami: w PostgreSQL przez Citus lub narzędzia aplikacyjne, w MySQL przez Vitess. To porównanie PostgreSQL i MySQL pokazuje, że oba systémy są produkcyjne, ale preferują inne kompromisy.
Zgodność ze standardem SQL
PostgreSQL jest bliżej standardu SQL: ścisłe CHECK, pełne CTE (w tym rekursywne), bogate funkcje okienkowe i MERGE od wersji 15. MySQL historycznie miał luźniejszą semantykę (np. GROUP BY bez wszystkich kolumn). Współcześnie tryb ONLY_FULL_GROUP_BY i STRICT przybliża go do standardu, ale różnice PostgreSQL MySQL pozostają w szczegółach składni i zachowania.
Różna jest też składnia upsert. PostgreSQL: INSERT ... ON CONFLICT DO UPDATE (zgodne z indeksem/kluczem). MySQL: INSERT ... ON DUPLICATE KEY UPDATE (sprzężone z naruszeniem unikalności). W obu silnikach CTE są od MySQL 8.0, ale PostgreSQL częściej realizuje złożone optymalizacje (inlining CTE zależny od planisty).

MySQL — Jak zacząć? Darmowy e-book
Praktyczny przewodnik po świecie SQL. Poznaj typy danych, zapytania SELECT, JOIN, funkcje agregujące i nie tylko.
Typy danych i ich obsługa
PostgreSQL ma bogatszy zestaw typów: JSONB z indeksowaniem GIN, tablice, zakresy (tsrange, numrange), ENUM, HSTORE oraz typy geometryczne. MySQL ma natywny JSON (dokładnie walidowany), ale bez równoważnika JSONB; do wydajnego filtrowania często używa się kolumn generowanych i indeksów. Dla precyzyjnych obliczeń numerycznych PostgreSQL oferuje numeric z dobrą kontrolą skali; MySQL także, ale detale zaokrągleń i konwersji mogą się różnić.
Różnice obejmują też indeksowalność wyrażeń. PostgreSQL ma indeksy na wyrażeniach i indeksy częściowe. MySQL wspiera tzw. functional indexes (na wyrażeniach) od 8.0.13, ale nie ma indeksów częściowych; najczęściej używa się kolumn generowanych PERSISTENT jako obejścia. Więcej w artykule: Typy danych: PostgreSQL vs MySQL.
Indeksy i wydajność
Domyślny indeks to B-tree w obu. PostgreSQL ma dodatkowo GIN/GiST/SP-GiST/BRIN, indeksy częściowe, na wyrażeniach i operator klasy. To daje przewagę w wyszukiwaniu pełnotekstowym (pg_trgm), JSONB i geodanych (PostGIS). MySQL oferuje FULLTEXT (InnoDB), indeksy przestrzenne (R-Tree dla MyISAM, InnoDB wspiera SPATIAL), invisible indexes i functional indexes. Brak indeksów częściowych bywa ograniczeniem w selektywnych warunkach.
Wydajność PostgreSQL vs MySQL zależy od profilu zapytań. PostgreSQL ma rozbudowany planista i statystyki wielokolumnowe, z joinami hash/merge/nested loop. MySQL 8.0 dodał hash join i EXPLAIN ANALYZE, ale wciąż częściej opiera się na nested loop i hintach skromniejszych niż w Oracle. Przy analityce i złożonych filtrach JSON/tekst PostgreSQL zwykle wygrywa; przy prostych OLTP na krótkich indeksach InnoDB jest bardzo konkurencyjny. Więcej dowiesz się z artykułu: Indeksy w SQL: teoria i praktyka.
Transakcje i poziomy izolacji
Oba silniki są ACID, ale domyślne zachowanie różni się. PostgreSQL domyślnie używa READ COMMITTED i MVCC bez blokad odczytu; REPEATABLE READ w PostgreSQL to Snapshot Isolation, a SERIALIZABLE to SSI (wykrywa konflikty zamiast blokować). MySQL InnoDB domyślnie używa REPEATABLE READ z next-key locks, co może oznaczać więcej blokad przy wstawieniach, ale mniejszą podatność na fantomy.
W praktyce „blokady vs wersjonowanie" przekładają się na inne profile opóźnień pod obciążeniem. PostgreSQL wymaga VACUUM/auto-VACUUM do sprzątania starych wersji, MySQL ma purge w InnoDB. W obu są SAVEPOINT-y, spójne snapshoty i tryb autocommit. Głębiej opisuję to w artykule: Transakcje i poziomy izolacji w SQL.
Funkcje okienkowe i CTE
Funkcje okienkowe są pełne w PostgreSQL od lat; MySQL wprowadził je w 8.0 (OVER, PARTITION BY, klauzule ramek). CTE są w obu, w tym rekursywne. W PostgreSQL planista częściej inline’uje CTE, gdy to korzystne; w MySQL niektóre CTE materializują się częściej, co wpływa na wydajność. Dla analityki to kluczowy obszar, gdzie porównanie PostgreSQL i MySQL zwykle wskazuje przewagę PostgreSQL.
Przykład działający w obu (MySQL 8.0+, PostgreSQL 12+): biegąca suma sprzedaży per klient z użyciem CTE i okna.
SQL1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16WITH t (id, customer_id, amount, sale_date) AS ( SELECT 1, 10, 100.00, CAST('2024-01-01' AS DATE) UNION ALL SELECT 2, 10, 50.00, CAST('2024-01-02' AS DATE) UNION ALL SELECT 3, 20, 70.00, CAST('2024-01-01' AS DATE) ) SELECT customer_id, sale_date, amount, SUM(amount) OVER ( PARTITION BY customer_id ORDER BY sale_date, id ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) AS running_amount FROM t ORDER BY customer_id, sale_date, id;
Więcej praktycznych przykładów znajdziesz w artykule: Funkcje okienkowe w PostgreSQL i MySQL.
Rozszerzalność i ekosystem narzędzi
PostgreSQL jest silnie rozszerzalny: własne typy, operatory, indeksy, języki procedur (plpgsql, plpython), FDW do zdalnych źródeł, oraz ekosystem rozszerzeń (PostGIS, pg_trgm, hstore, timescaledb, citus). MySQL ma wtyczki (uwierzytelnianie, audit, pełny tekst) i UDF, ale zakres rozszerzalności rdzenia jest mniejszy.
Narzędzia: PostgreSQL ma psql, pg_dump/pg_restore, EXPLAIN ANALYZE z profilowaniem operatorów, auto_explain i pg_stat_statements. MySQL ma mysql, MySQL Shell, mysqldump, EXPLAIN ANALYZE i Performance Schema. W integracji chmurowej oba mają dojrzałe oferty (RDS/Aurora, Cloud SQL, AlloyDB, HeatWave), lecz strategie skalowania analityki i sharding różnią się (np. Citus vs Vitess). To są praktyczne różnice PostgreSQL MySQL dla architektów.
Co wybrać do nauki – PostgreSQL czy MySQL
Jeśli celujesz w analitykę SQL, złożone zapytania, geodane lub intensywny JSON, zacznij od PostgreSQL. Jeśli pracujesz w środowisku LAMP, z typowym OLTP, i liczysz na szerokie wsparcie hostingów, MySQL będzie równie dobrym wyborem. W wielu firmach spotkasz oba, więc znajomość „PostgreSQL vs MySQL” realnie zwiększa elastyczność.
Start praktyczny: podstawy SQL, EXPLAIN/ANALYZE, indeksy i transakcje. Potem funkcje okienkowe i CTE, a na końcu replikacja i narzędzia backupu. Gdy pytasz „PostgreSQL czy MySQL”, odpowiedź zależy od workloadu: analityczny i rozszerzalny – PostgreSQL; prosty OLTP z naciskiem na latencję – MySQL.

Kurs SkumajBazy — Czas w końcu nauczyć się SQLa
Kompleksowy kurs SQL dla programistów, analityków i wszystkich, którzy chcą efektywnie pracować z danymi. Od podstaw do zaawansowanych zapytań.



