Porównanie wydajności baz danych (MySQL, PostgreSQL)

Po wczorajszych testach, i pamiętnych flame’ach MySQL vs PostgreSQL, postanowiłem sprawdzić jak się mają te 2 bazy do siebie w kwestii prostych zapytań na tabelach z 2 mln wierszy każda (liczby i stringi), w przypadku indeksowanych kolumn, i nie.

Zapytanie INDEX MySQL PostgreSQL
SELECT COUNT(id) FROM liczby 1 rows fetched (844 ms) 1 rows fetched (719ms)
SELECT id FROM liczby
WHERE liczba = 67
NIE 55 rows fetched (1,078 s) 20533 rows fetched (735 ms)
SELECT id FROM liczby
WHERE liczba = 67
TAK 55 rows fetched (141 ms) 20533 rows fetched (234 ms)
SELECT COUNT(id) FROM stringi; 1 rows fetched (859 ms) 1 rows fetched (828 ms)
SELECT id FROM stringi
WHERE string=’HDDFBAGFHCABIBIAFAAE’;
NIE 1 rows fetched (1,172 s) 1 rows fetched (1,016 sec)
SELECT id FROM stringi
WHERE string=’HDDFBAGFHCABIBIAFAAE’;
TAK 1 rows fetched (16 ms) 1 rows fetched (15 ms)

Dla tabel z 0.6 mln wierszy wyniki przedstawiają się następująco:

Zapytanie INDEX MySQL PostgreSQL
SELECT COUNT(id) FROM liczby 1 rows fetched (265 ms) 1 rows fetched (188 ms)
SELECT id FROM liczby
WHERE liczba = 67
NIE 55 rows fetched (312 ms) 6170 rows fetched (193 ms)
SELECT id FROM liczby
WHERE liczba = 67
TAK 55 rows fetched (47 ms) 6170 rows fetched (31 ms)
SELECT COUNT(id) FROM stringi; 1 rows fetched (265 ms) 1 rows fetched (234 ms)
SELECT id FROM stringi
WHERE string=’HDDFBAGFHCABIBIAFAAE’;
NIE 1 rows fetched (359 ms) 1 rows fetched (250 ms)
SELECT id FROM stringi
WHERE string=’HDDFBAGFHCABIBIAFAAE’;
TAK 1 rows fetched (15 ms) 1 rows fetched (16 ms)

Jak widać, dla 2mln wierszy z warunek, gdzie kolumna jest nieindeksowana wygrywa PostgreSQL, przy kolumnie typu INTEGER widać znaczącą przewagę.
Ale jeśli już utworzymy indeksy, różnicy nie ma (typ VARCHAR), lub jest nieznaczna (INTEGER).

Sytuacja ma się zupełnie inaczej, jeśli mamy mniej niż  1 mln wierszy, w przykładzie ponad 0.6 mln.
W każdym przypadku PostgreSQL jest lepiej zoptymalizowany, nawet po utworzeniu indeksu dla kolumny INTEGER. Takie same wyniki (z przybliżeniem) są tylko dla kolumn indeksowanych VARCHAR.

Oczywiście czasy na poszczególnych maszynach, wersjach baz danych mogą się różnić. Testy robiłem wyłącznie na jednej maszynie, która nie jest wyłącznie przeznaczona na serwer bazodanowy.

Poniżej zastosowane funkcje dla PostgreSQL (wzorowane na poprzednich procedurach dla MySQL):

Aktualizacja (2009-06-19 14:20)
Polecam również MySQL vs PostgreSQL Benchmarks