Każdy kto choć raz miał styczność z mongo i bazami SQL wie, że bazy nie nadają się na środowiska zwirtualizowane. Obojętnie czy to VPS czy Cloud. Ten cały benchmark, przeprowadzony z resztą koszmarnie ma pewnie udowodnić z góry założoną tezę. Właściwie nie widziałem dawno tak źle przeprowadzonego porównania.
Nie da się przeprowadzić testów wydajności na podstawie pomiaru czasu jednego zapytania. Bo równie dobrze można by po prostu zrobić to samo używając funkcji RAND. Trzeba wyłączyć cache i zmierzyć czas wykonywania 1000, 2000 zapytań a nie jednego. Na nieobciążonym systemie a nie na jakimś VPS-ie gdzie inni wpływają na wyniki pomiarów.
Benchmarków się w ogóle nie przeprowadza na maszynach zwirtualizowanych, są zbyt niestabilne i wyniki mogą się różnic w czasie o kilka tysięcy %. Tutaj mamy zdaje się nawet nie maszynę wirtualną, tylko obciążony hosting VPS. I widać jakie głupoty wychodzą, count(*) szybsze pod innodb niż pod myisam(

!). Przecież to woła o pomstę do nieba. W myisam się po prostu bierze wartość z pamięci a w innoDB trzeba przeprowadzić full table/index scan czyli "przelecieć" wszystkie wiersze albo cały index. Równie dobrze gość mógłby przetestować szybkość indeksów i by mu wyszło że szybsze jest skanowanie całej tabeli(!). Połowa tego testu to nie pomiar wydajności rozwiązań bazodanowych, co pomiar bezwładności dociążonej maszyny wirtualnej.
mysql ma być szybki i niezawodny (ACID). mongo elastyczne i skalowalne. To są zupełnie inne systemy i zupełnie inne założenie, mongo się nadaje na VPS-y czy chmurę, bazy SQL - w żadnym wypadku. Bo nawet jeśli dołożyć warstwę wirtualizacji i przydzielić całe dostępne zasoby jednemu użytkownikowi to i tak wydajność baz zmniejsza się o 30-40%, nie mówiąc już o testach gdy na maszynie są inni ludzie zamulający I/O czy bardzo wolne I/O po sieci (NAS).
Najśmieszniejsze jest to, że zła konfiguracja mysql w tym teście doprowadziła do tego, że trzeba było ubić serwer. To już po prostu magia. Stare wersje mysql-a mogą chodzić na serwerze bez problemów przez kilka lat(!) tu się wysypał prosty SELECT .. WHERE. I te koszmarne wyniki postgresa. Od razu widać, że coś jest nie tak z konfiguracją, proste kwerendy nie mają PRAWA tak długo się wykonywać. Gdyby SELECT na paru rekordach w PG zajmował pół sekundy to ten projekt zdechłby 10 lat temu, bo to 10 lat temu był wynik nie do przyjęcia.
Dodatkowo wiersz w mysql to czyste dane. mongo musi przechowywać 16 bajtowy(!) UID + całą strukturę danych, bo wszystko jest zapisywane przy użyciu JSON i identyfikatorów unikalnych globalnie które są po prostu OGROMNE. Oznacza to często, że pojedyncze rekordy zajmują od kilku do kilkudziesięciu razy więcej pamięci niż to samo zapisane w klasycznej bazie danych. Akurat przeprowadzałem jakiś czas temu tekst z importem tabeli 1GB (ID + słowo) do mongo. Po zaimportowaniu 10% dane w mongo zajmowały już 2GB. Z polskiego na nasze - mongo się nie nadaje do zastosowań gdzie występują duże ilości rekordów. Chyba że mamy dużo zapisów i już absolutnie inaczej tego nie można przeskalować. To ostateczność. Bo jeśli w mysql wystarczy 1 serwer a w mongo potrzeba 10, żeby przechować to samo, to logiczne że ktoś wybierze mongo tylko wtedy, jeśli niemożliwa jest replikacja albo sharding w klasycznej bazie danych.
Więc to się w ogóle nie nadaje do czegoś takiego jak wyszukiwarka, zwłaszcza, że dane indeksera będziesz prawdopodobnie w 99% przypadków czytał a nie uaktualniał więc nawet w SQL-u się to da prosto skalować używając prefixów.
Cytat
Ważnym jest również to ile danych będzie w bazie, jeżeli będzie ich np. miliard
To masz 16GB na same UID-y + 16GB na strukturę rekordu w mongo. Czyli 32GB śmietnika, zanim jeszcze cokolwiek zapiszesz (i to dla samego indeksera). Reverse index ma większy sens... mniejszy narzut. Tylko przechowywanie 128 bitowego UUID dla każdego słowa to głupota, trzeba ograniczać ilość bajtów dla RI. Bo tak to masz 16bajtów x miliard wierszy (a mogłyby być 4 bajty x miliard wierszy). Więc teoretycznie można by zaimplementować rozproszony reverse index w nodejs (jakieś 2 godziny roboty), przeszukiwanie z wildcard na końcu wyrazów jako rozproszone bazy mysql.
>To bardzo ważna kwestia, która chyba przesądza na korzyść bazy nierelacyjnej.
Tylko problem jest taki, że AFAIK nie ma bardziej nieefektywnej bazy nierelacyjnej niż mongo. Można by od biedy wykorzystać jakiś REDIS (bo wspiera listy i AFAIR nie pakuje do pamięci tyle niepotrzebnego syfu) jako reverse index ID=>DOCID1, DOCID2, DOCIDx i zrobić wyszukiwanie wyrazów w mysql (słowo => ID) a całość podzielić na kilkaset tabel używając prefixów.