Co ma język do jakości optymalizatora?
Nie chodziło o jakość optymalizatora, ale to trudności napisania optymalizatora.
Trudność napisania optymalizatora jest zależna głównie od semantyki języka zapytań oraz od tego co pod spodem wspiera baza danych, a nie od składni języka. Składnia to naprawdę najmniejszy problem. CQL cassandry jest składniowo bardzo podobny do SQLa (celowo), a optymalizacja jest trywialna w porównaniu z SQLem. Głównym powodem jest brak złączeń w Cassandrze. Domyślam się, że w Mongo będzie podobnie, bo Mongo też nie obsługuje złączeń, a złączenia (i podzapytania, i wykorzystanie perspektyw zmaterializowanych) są jednymi z najtrudniejszych elementów optymalizatora. Żadnej z tych rzeczy nie ma w Mongo, więc optymalizator ma je "z głowy".
Sam optymalizator nie musi być wcale bardzo szybki, musi za to dawać dobre plany zapytań, a to jest łatwiej uzyskać pisząc go w języku wysokiego poziomu.
W połowie zgodzę się z Tobą, często, może właśnie w połowie przypadków, jest tak jak napisałeś. Ale zwróć uwagę na dwie sprawy:
Jeśli zapytanie na kiepskim planie wykonuje się 1.0s, na dobrym planie 0.9s, a (wolny) optymalizator działa 0.3s, to sam rozumiesz że samo użycie optymalizatora już szkodzi.
A kto Ci każe przygotowywać plan zapytania za każdym razem?
Jeśli wolny optymalizator napiszemy np. w Pythonie, a taki sam wydajny w C++, to ten w C++ w tym samym czasie może wykonać około 100 razy więcej obliczeń, więc może lepiej zoptymalizować.
Tyle, że po pierwsze różnica między JS a C++ nie wynosi 100x a co najwyżej 10x, a po drugie przy braku złączeń to kompletnie nie ma znaczenia, bo liczba planów jaką musi rozważyć optymalizator jest zwykle w zakresie "jeden do kilkadziesiąt", z naciskiem na "kilka". W większości NoSQLi nie ma czegoś takiego jak wydzielony optymalizator, bo wyszukiwanie po kluczu głównym robi się zawsze tak samo. W zasadzie jedynym polem do popisu dla optymalizatora jest wybór odpowiedniego indeksu, ale tu zwykle też nie ma co optymalizować, tylko po prostu stosuje się heurystykę zachłanną typu "zacznij od warunku, który ma najlepszą selektywność i dla którego mamy jakiś indeks".
Z kolei silnik składowania danych Mongo jest napisany w C++, oparty o pliki mapowane pamięciowo i nie ma tam ani jednej linijki w JS. Jest to swoją drogą beznadziejna decyzja projektowa, która powoduje, że MongoDB dostaje solidne bęcki praktycznie w każdym benchmarku, gdzie ilość danych przekracza rozmiar dostępnego RAMu. Nawet od baz napisanych w Javie :P
Nie mam szczegółowej wiedzy na temat Mongo, więc nie wiem czy dostaje lanie czy nie. Ale na pewno popełniasz kilka błędów:
Java jest językiem kompilowanym, bardzo wydajnym, a wąskim gardłem może być dostęp do danych w RAM lub dysku, więc napisanie 'nawet w javie' jest pomyłką
Z tego sobie akurat zdaję sprawę. To było miało być troszkę ironiczne odniesienie do dyskusji czy JS przeszkadza w napisaniu szybkiej bazy.
Proponuję eksperyment: Weź jakąś listę, wektor danych nawet w RAM, napisz jakiś bardziej skomplikowany warunek nawet w C++, potem uruchom fullscan i zobacz jaki będzie czas wykonania gdy ilość danych zajmie pamięć dzisiejszego mocnego komputera (np. 64-256GB). Potem odpowiedz sobie na pytanie, jak często taki czas oczekiwania na odpowiedź jest dopuszczalny. Wniosek będzie oczywisty: gdy dane przekraczają bufor ram, to dostawiamy kolejny sharder i mongo daje właśnie takie możliwości. Baza postgres niby też daje takie możliwości, ale map-reduce trzeba zrobić sobie samemu, a w mongo jest gotowe.
RAM jest drogi, znacznie droższy od SSD, a SSD jest z kolei znacznie droższe od HDD. Trzymanie wszystkich danych w RAMie to bezsensowne marnotrawstwo pieniędzy, no chyba że faktycznie nasz zbiór danych mieści się w kilkudziesięciu GB. Te dodatkowe shardery kosztują. Trzeba je kupić, mieć na nie miejsce, a następnie serwisować. No i prąd z gniazdka za darmo nie jest. Dlatego wydajność bazy danych dla zbiorów przekraczających wielkość RAMu jest nadal bardzo istotnym aspektem i jeszcze długo będzie.
BTW: "Fullscan" 256 GB danych w RAMie zajmie co najmniej kilka sekund, bez robienia czegokolwiek ciekawego z tymi danymi - tylko przesłanie ich z RAM do cache L1. W praktyce jeśli chcemy z tymi danymi coś zrobić, to raczej kilka minut. Jest to czas nieakceptowalny dla większości systemów baz danych, gdzie oczekiwane są odpowiedzi w czasie poniżej milisekundy, a nie w sekundach. Hurtowe przeglądanie danych jest interesujące tylko dla analityków.
Nie daje.
https://aphyr.com/posts/322-jepsen-mongodb-stale-reads
In this post, we’ll see that Mongo’s consistency model is broken by design: not only can “strictly consistent” reads see stale versions of documents, but they can also return garbage data from writes that never should have occurred
Ktoś kłamie, nie wiem kto:
http://student.agh.edu.pl/~chamot/bazy/
[
Załózmy, że kilka procesów na raz chce dodać wartość w tabeli 'groups'. Klient nie musi sie martwić o transakcyjność. MongoDB rozwiązuje ten problem. Każda operacja zmieniająca stan dokumentu usuwa go oraz wstawia nowy, zaktualizowany. System bazy danych dba o synchronizację tych dwóch operacji tak, by każdy klient widział te same dane.
]
Czytałeś to w ogóle? Wiesz w ogóle kim jest autor tego bloga, który podlinkowałem i czym się zajmuje? Reputacja Aphyra (a dokładniej: Kyle Kingsbury, bo Aphyr to tylko psudo) miażdży reputację jakiegoś losowego tutoriala z netu, na dodatek pisanego dla wąskiej grupy odbiorców i to prawdopodobnie tylko na podstawie dokumentacji do Mongo. "System baz danych dba o synchronizację by każdy klient widział te same dane." - Bullshit, jakbym słyszał jakiegoś marketingowca. Może dba, ale mu to nie wychodzi, co Aphyr udowodnił. Aphyr stosuje naukową metodologię w swoich testach baz danych, a kod Jepsen jest otwarty i używany przez niektórych vendorów jako część oficjalnych testów (Cassandra regularnie przechodzi te testy przed każdym releasem). Jeśli tekst Cię nie przekonuje, że MongoDB ma problemy ze spójnością danych, to możesz wykonać wszystkie testy samodzielnie. W wyniku testów Jepsen w różnych bazach danych zostały poprawione dziesiątki błędów (nie tylko w Mongo, w Cassandrze również).
- Bo ma proste i dość spójne API. Zapytania w JS. Dane w JS. Wyniki zapytań w JS. JS każdy prawie zna, a jak nie zna, to w podstawowym zakresie może się w dzień nauczyć.
Moim zdaniem SQL jest prostszy.
Kwestia gustu.
- Bo można je szybko postawić na laptopie i od razu działa bez większych ceregieli.
Z bazami SQL mam mniej problemów. Np. drivera mongodb do C++ nie udało mi się skompilować, pomimo że poświęciłem na to cały dzień.
To że Ty miałeś problem nie oznacza, że inni mają. Mnie kiedyś postawienie Oracle zajęło 3 dni. Ogólnie jak gadam z ludźmi na różnych konferencjach, to nie mają problemów z postawieniem / używaniem Mongo na jednej maszynie. Schody są przy skalowaniu. Mamy dużo firm, które przeniosły się z Mongo na Cassandrę i jakoś nikt nie podnosił problemów, że "Mongo jest trudne".
- Bo przez brak sztywnego schematu daje poczucie, że nie trzeba jakoś bardzo projektować modelu danych. Jak zabraknie jakiegoś pola czy trzeba będzie zmienić strukturę, to się zmieni później i Mongo wszystko łyknie.
Do tabeli sqlowej też można dodać pole.
I jeśli tabela ma kilkadziesiąt TB, to będzie trwało to dzień, a wszystkie zapytania do tej tabeli w tym czasie nie będą działać, albo będą działać na 1/10 swojej wydajności, bo większość RDBMSów musi w takiej sytuacji przepisać całą tabelę na nowo. Poza tym w przypadku Mongo cała heca polega na tym, że nic nie trzeba robić z samą bazą. Wystarczy wrzucić nową wersję aplikacji.
- Bo jest dość szybkie o ile nie wychodzimy poza RAM.
Nie widziałem dużo dobrych porównań, ale w tym co widziałem, to (na jednym sharderze) mongo raczej było wolniejsze niż postgresql.
Nie widziałem niestety dobrych porównań mongo vs postgres. Teoretycznie nie ma powodów, aby baza danych typu MongoDB miała być wolniejsza, za to jest mnóstwo powodów dla których Postgres powinien być powolniejszy na jednym węźle. Ale możliwe, że Mongo ma jeszcze nadal jakieś problemy - nigdy nie należało do najszybszych NoSQLi, kiedyś miało global lock, który dość mocno negatywnie odbijał się na wydajności. Natomiast postgres nie ma szans z NoSQLami, które potrafią zapisywać/odczytywać z szybkością kilkadziesiąt-kilkaset tysięcy losowych wierszy na sekundę na jednym węźle i w milionach / s na klastrze przy bazach mających setki lub tysiące TB (AmazonDB, Cassandra, HBase itp). Nie ta skala. Postgres jest świetną bazą, ale transakcyjność ma olbrzymi wpływ na wydajność i skalowanie. Pamiętam, że jak mieliśmy 100 transakcji na sekundę z pojedynczego serwera, to był już szał i powód do świętowania.
- Wydajność ssie dla dużych zestawów danych wychodzących znacznie poza RAM.
Jeśli wydajność jest ważna to w ogóle inne obliczenia niż w RAM odpadają, no chyba że mamy tylko proste zapytania i można zrobić bezpośredni skok do zaindeksowanego rekordu.
Cała sztuka właśnie polega na tym, aby tak zorganizować dane by nie robić innych operacji jak skoki do zaindeksowanych rekordów.
</quote>
- Większość gwarancji odnośnie spójności danych nie jest prawdziwa.
No nie wiem, jakie jest źródło tej informacji?
Podałem, ale widać nie przeczytałeś.
To jeszcze raz:
https://aphyr.com/posts/284-jepsen-mongodb
https://aphyr.com/posts/322-jepsen-mongodb-stale-reads
vpiotr