Sorry - bazy danych (SQL i NOSQL) dzialaja na mnie jak plachta na byka. (Coz, zaczalem programowac jak tego gowna jeszcze nie bylo w mainstreamie).

- Rejestracja:około 21 lat
- Ostatnio:prawie 3 lata
- Lokalizacja:Space: the final frontier
- Postów:26433
@artur_bredzki bredzisz albo nie doczytałeś co pisałem w twoim poprzednim temacie. Twierdziłeś tam że:
20mln rekordów w RAM to można na fullskanie przetworzyć w parę milisekund
A teraz wyskakujesz z:
aby tamto zapytanie działało w góra 10ms na zbiorze o rozmiarze powiedzmy 0.5TB. Myślę, że to nie jest ciężki wymóg
Na jednym CPU to będzie niewykonalne i tyle jeśli zakładamy że te 0.5TB to są miliardy małych rekordów. Już ci wyjaśniałem ze 3GHz procesor może w ciagu milisekundy wykonać 3 mln cykli zegarowych. Więc ty chcesz w 30 mln cykli zegarowych przetworzyć powiedzmy 500 mln rekordów (już i tak zakładam spory 1MB rekord), czyli chciałbyś żeby procesor przetworzył ci 17 rekordów bazodanowych w ciągu 1 cyklu zegarowego a w warunkach masz kilkadziesiąt porównań. Bez zaginania czasoprzestrzeni to się nie obejdzie.
Oczywiście to moze zadziałać o ile będziesz miał tam warunki które mocno ograniczą zestaw danych wejściowych i od razu indeksem obetniesz 95% danych, ale full scan po prostu nie ma szans.
- Rejestracja:prawie 9 lat
- Ostatnio:ponad 8 lat
- Postów:229
Jarek000000 napisał(a):
Bazy danych do przechowywania danych operacyjnych - zbiroru roboczego sa bez sensu od wielu lat. To bylo rozwiazanie z lat 90 jak bylo w komputerach po 120MB pamieci (a 2GB to byly duze zbiory danych).
Nie tylko spowalniaja ale tez totalnie psuja kod, przejrzystosc systemu i przeszkadzaja w efektywnej wspolbieznosci.
Zreszta bierzcie moje video:
https://vimeo.com/170796157
Przepraszam, wideo teraz nie mogę obejrzeć. Ale to co piszesz o zbiorze roboczym, nie musi być prawdą. Musi być spełnionych kilka warunków i bazy nadają się do przechowywania zbioru roboczego, te warunki to:
- baza posiada i wykorzystuje odpowiednie indeksy do danego zadania
- jest wystarczająca ilość ram
- narzut na transfer i parsowanie zapytań nie jest problemem.
Jeśli te warunki są spełnione, to co jest problemem aby przechowywały zbiór roboczy?
Shalom napisał(a):
@artur_bredzki bredzisz albo nie doczytałeś co pisałem w twoim poprzednim temacie. Twierdziłeś tam że:
20mln rekordów w RAM to można na fullskanie przetworzyć w parę milisekund
A teraz wyskakujesz z:
aby tamto zapytanie działało w góra 10ms na zbiorze o rozmiarze powiedzmy 0.5TB. Myślę, że to nie jest ciężki wymóg
Możemy pozostać przy 20mln rekordów. Jeśli da radę na 20mln, to da radę na dowolnym zbiorze - rzecz jasna tamto zapytanie, a nie ogólnie.
Shalom napisał(a):
Na jednym CPU to będzie niewykonalne i tyle jeśli zakładamy że te 0.5TB to są miliardy małych rekordów. Już ci wyjaśniałem ze 3GHz procesor może w ciagu milisekundy wykonać 3 mln cykli zegarowych.
3 miliardy.
Shalom napisał(a):
Więc ty chcesz w 30 mln cykli zegarowych przetworzyć powiedzmy 500 mln rekordów (już i tak zakładam spory 1MB rekord), czyli chciałbyś żeby procesor przetworzył ci 17 rekordów bazodanowych w ciągu 1 cyklu zegarowego a w warunkach masz kilkadziesiąt porównań. Bez zaginania czasoprzestrzeni to się nie obejdzie.
Oczywiście to moze zadziałać o ile będziesz miał tam warunki które mocno ograniczą zestaw danych wejściowych i od razu indeksem obetniesz 95% danych, ale full scan po prostu nie ma szans.
Oczywiście że nie metodą fullscan.
Krolik napisał(a):
- słaby lub nieadekwatny system baz danych (tak, widziałem kolesia, który chciał budować system o skali Allegro na PHP i MySQLu na jednym serwerze).
Odbiegając od głównego tematu: mam informację z niepotwierdzonego źródła, że serwis stackoverflow działa zaledwie na 4 komputerach. Można domyślać się, że są to bardzo wydajne komputery, no ale i tak 4 komutery wydaje się o dwa rzędy wielkości za mało. Możliwe jest to rzekomo dzięki temu, że używają bazy REDIS. Jak sądzicie, to że stoi na 4 komputerach jest prawdą, czy bzdurą? Inna sprawa, czy można się skądś dowiedzieć, na ilu serwerach działa allegro?
artur_bredzki napisał(a):
Przepraszam, wideo teraz nie mogę obejrzeć. Ale to co piszesz o zbiorze roboczym, nie musi być prawdą. Musi być spełnionych kilka warunków i bazy nadają się do przechowywania zbioru roboczego, te warunki to:
- baza posiada i wykorzystuje odpowiednie indeksy do danego zadania
- jest wystarczająca ilość ram
- narzut na transfer i parsowanie zapytań nie jest problemem.
Jeśli te warunki są spełnione, to co jest problemem aby przechowywały zbiór roboczy?
Problem to brzydki i slabo testowalny kod.
Czasem bazy sie przydaja np. robienia roznych raportow ... ale nie do przechowywania.
See:
- Rejestracja:prawie 9 lat
- Ostatnio:ponad 8 lat
- Postów:229
Jarek000000 napisał(a):
Sorry - bazy danych (SQL i NOSQL) dzialaja na mnie jak plachta na byka. (Coz, zaczalem programowac jak tego gowna jeszcze nie bylo w mainstreamie).
Gdy ja zaczynałęm programować, a właściwie gdy już trochę programowałem, to przychodzili do mnie z zapytaneim sql które nie działalo na DOS+DBase, żebym napisał w C++ :) Piszę poważnie, takie miałem pierwsze praktyki z programowania w większej firmie. No ale teraz dużo się zmieniło, często rozwiązania na bazach danych dają rady.

- Rejestracja:ponad 13 lat
- Ostatnio:około 3 lata
- Lokalizacja:Grudziądz/Bydgoszcz
- Postów:5300
I tak nikt tego postu nie zauważy albo dostane info, ze mówię nieprawdę dlatego chciałbym z tego miejsca pozdrowić wszystkie pokemony na świecie :)

- Rejestracja:ponad 9 lat
- Ostatnio:około miesiąc
- Postów:105
Punkt widzenia zależy od punktu siedzenia.
Osobiście nie widzę innego rozwiązania dla firmy w której pracuje 200 osób + obsługiwanej przez program który nie jest oparty względem logiki o jakiś RDBMS.
W większości przypadków mój punkt widzenia przyjmuje większość udzielająca się w tym wątku, stąd takie małe zrozumienie dla twojej interpretacji problemu.
Lecz faktem jest że w niektórych przypadkach pewne zastosowania są bardziej wydajne, przykładem będzie porównanie dwóch algorytmów sortujących, temat oklepany ale mam tutaj na myśli sortowanie bąbelkowe a sortowanie szybkie ( qsort ), jak wiemy dla dużej ilości danych sortowanie szybkie zabija bąbelkowe, natomiast dla małej ilości danych.. no cóż podobnie albo i lepiej dla sortowania bąbelkowego. Czy bazy danych są nieefektywne? Oczywiście że nie, są bardzo efektywne i zapewniają bardzo dużo mechanizmów dzięki którym mamy zaoszczędzony czas, czas na tworzenie jakiś własnych wypocin. Mało tego, z autopsji wiem że klientowi bardziej zależy na działaniu programu jak na jego super ultra wydajności, bo klient będzie bardziej wściekły tym że stracił dane które uzupełniał miesiącami, latami niż tym że dopisują się one powoli ale w sposób kontrolowany ( czyli z użyciem transakcji, triggerów etc. ) oraz owe dane może uzupełniać kilkaset osób jednocześnie. Z jednym się zgodzę i powtórzę już to jaka n osoba z rzędu, bazy są wolne ponieważ leżą na dysku, ale mam na myśli wolne względem ramu. Lecz co w przypadku gdy mamy w RAM'ie trzymać 700GB danych? które przedsiębiorstwo zgodzi się na zakup clustra ( nie wspomnę o kwotach np. SQL Server i kosztach licencji wyliczanej na podstawie ilości wątków serwera ).
Ale nie wykluczam że za kilkanaście lat takie rozwiązanie nie będzie jednym z lepszych, bo może się okazać że 4TB ram to będzie standard, póki co.. daj sobie spokój, bo sam nawet w kilka lat nie napiszesz nic lepszego od SQLLite.
Poza tym znam kilka mechanizmów takich jak ARRAY_DML + CacheUpdates dzięki którym dopiszesz setki tysięcy rekordów w bardzo krótkim czasie.
I jeszcze tak napomnę, SELECTY są zazwyczaj wolne gdy wykonujesz w nich podzapytania, dodatkowo działa jakiś trigger no i łączysz pewne tabele ze sobą relacyjnie, jeżeli chcesz szybko wyświetlać dane w jakimś gridzie, to nie wyświetlaj od razu 1 000 000 rekrów, tylko rozłóż to na paczki, ograniczające się do zasięgu widoczności grida czy tam jakiegoś view. Bo po co komu wczytać wszystko skoro i tak tego nie zauważy. Może warto byłoby zagłębić się w poznanie jakiś mechanizmów/sztuczek programistycznych jak krytykować "wolne systemy" ( sam kiedyś narzekałem na pewne rozwiązanie zwane FireDac, okazało się że moje problemy były spowodowane nieznajomością tego mechanizmu, zagłębienie się w manuale pomogło mi zrozumieć moje błędy i zmusiło do refleksji oraz rachunku sumienia ). Co do tego zasięgu widzenia, coś takiego stosują silniki gier, nie pamiętam fachowej nazwy tego mechanizmu, ale obiekty zasłonięte przez inne nie są po prostu renderowane i GPU nie oblicza ich vertexów i pixeli, a przecież nikt i tak tego nie zauważy. Pozdrawiam P.
<quote="1275642">Punkt widzenia zależy od punktu siedzenia.
Osobiście nie widzę innego rozwiązania dla firmy w której pracuje 200 osób + obsługiwanej przez program który nie jest oparty względem logiki o jakiś RDBMS.<quote>
To jest chyba sedno problemu. A probowales kiedys innego rozwiazania? Akka-persistence, CQRS, DDD, clean architecture etc.?
To, ze dziadowie pisali pod RDBMS - bo w latach 90tych to mialo sens - to nie znaczy, ze ma nadal.
- Rejestracja:prawie 9 lat
- Ostatnio:ponad 8 lat
- Postów:229
Deltech napisał(a):
Punkt widzenia zależy od punktu siedzenia.
Rzecz jasna.
Deltech napisał(a):
Osobiście nie widzę innego rozwiązania dla firmy w której pracuje 200 osób + obsługiwanej przez program który nie jest oparty względem logiki o jakiś RDBMS.
Myślę podobnie, wiele systemów, nie tylko tych dla 200osobowych firm, w ogóle by nie mogło zaistnieć, gdyby nie oprzeć go o bazę danych. Nie mogłoby zaistnieć z powodu kosztów.
Deltech napisał(a):
W większości przypadków mój punkt widzenia przyjmuje większość udzielająca się w tym wątku, stąd takie małe zrozumienie dla twojej interpretacji problemu.
Hmmmm
Deltech napisał(a):
Lecz faktem jest że w niektórych przypadkach pewne zastosowania są bardziej wydajne, przykładem będzie porównanie dwóch algorytmów sortujących, temat oklepany ale mam tutaj na myśli sortowanie bąbelkowe a sortowanie szybkie ( qsort ), jak wiemy dla dużej ilości danych sortowanie szybkie zabija bąbelkowe, natomiast dla małej ilości danych.. no cóż podobnie albo i lepiej dla sortowania bąbelkowego.
Owszem, jeden algorytm działa lepiej na malej ilości danych, drugi na dużej.
Deltech napisał(a):
Czy bazy danych są nieefektywne? Oczywiście że nie, są bardzo efektywne i zapewniają bardzo dużo mechanizmów dzięki którym mamy zaoszczędzony czas, czas na tworzenie jakiś własnych wypocin.
Zależy w jaki sposob porównywać. W pewnym sensie się zgodzę, że są efektywne, powiem nawet że są bardzo efektywne. Z kilku testów które wykonałem, wynika, że narzut bazy (w stosunku do programu który (praweie) optymalnie wykorzystuje sprzęt komputerowy) wynosi 20-50 razy. Narzut 30krotny może niektórym wydać się duży, ale jest to bardzo dobry wynik, choćby dlatego, że często języki interpretowane mają narzut 100 krotny. Ja byłem bardzo zaskoczony, gdy zobaczyłem, że baza potrafi wykonać zapytanie z narzutem 30krotnym - spodziewałem się narzutu 300 krotnego. Naprawdę uważam że bazy mogą być bardzo wydajne. Niemniej wydajność bazy danych może się uaktywnić po spełnieniu serii warunków. Tymi warunkami np. są:
- Baza udostępnia do danego typu zadania odpowiednie indeksy, np. w postgresie jakiś czas temu wprowadzono indeksy geometryczne i rozszerzenia earth; przed ich wprowadzeniem na postgresie trudno było postawić serwis randkowy, bo pani z Ameryki znajdowała sympatycznego pana, ale z odległej Rosji ;-)
- Baza danych, a właściwie jej optymalizator, musi bardzo dobrze wykorzystać indeksy, co z tego że indeks jest, jeśli optymalizator go źle wykorzysta?
- Baza musi wspierać odpowiednie buforowanie danych w RAM; jest wiele różnych strategii buforowania, w C++ teoretycznie można napisać sobie każdą strategię, w przypadku baz danych jesteśmy skazani na te które oferuje baza.
W typowych aplikacjach te wymagania często są spełnione. A nawet gdy spełnione nie są, nawet gdy baza danych działa w danym zastosowaniu bardzo nieefektywnie, to takie działanie bazy jest wystarczające, ponieważ może być mało danych. Jednak od czasu do czasu zdarza się aplikacja w której nie można sobie pozwolić na marnowanie mocy procesora. W takich aplikacjach wysyłamy zapytanie do bazy i mierzymy czas. Potem właśnie piszemy śmieszny programik w C++ i znowu mierzymy czas. Wychodzi że baza na coś przeznaczyła 99.9% mocy procesora. Owszem, baza dba o spójność danych, o bezpieczeństwo, ma zaimplementowany wielodstęp, transakcje, uprawnienia, jest przygotowana na przechowywanie setek terabajtów danych, umie wykonać zapytania łączące wiele tabel, umie inne cuda które długo by wyminać, no i z tych powodów ma też prawo trochę gorzej wykorzystać indeksy lub bufor ram niż wynikałoby to z teorii. W niektórych aplikacjach ja na to mówię: ale nie potrzebuję 100% spójności danych, nie potrzebuję transakcji, wielostęp załatwię jednym globalnym semaforem, uprawnienia rozwiązać można po stronie aplikacji, mam tylko jedną główną tabelę, i chyba potrafię w C++ dobrać optymalne indeksy i strategię buforowania dla danego problemu. Wtedy pozostaje tylko ostatnia kwestia: czy w daną aplikację warto tak dużo pracy włożyć? Jeśli warto i jeśli taką aplikację się ukończy, to ona naprawdę może działać 100 razy szybciej niż aplikacja oparta na relacyjnej bazie. Taka aplikacja może dzialać na 50 komputerach zamiast na 5000. Podobn stackowerflow pracuje tylko na 4 serwerach. Czy w takim przypadku też można powiedzieć, że RDBSM są efektywne? No chyba jednak nie?
Mało tego, z autopsji wiem że klientowi bardziej zależy na działaniu programu jak na jego super ultra wydajności, bo klient będzie bardziej wściekły tym że stracił dane które uzupełniał miesiącami, latami niż tym że dopisują się one powoli ale w sposób kontrolowany ( czyli z użyciem transakcji, triggerów etc. ) oraz owe dane może uzupełniać kilkaset osób jednocześnie.
Właśnie, są różne wymagania. Raz chemy mieć pewność 100% że wprowadzane dane nie zginą, drugi raz wystarczy 99.9%, bo gdy zginą, to np. można wpisać jeszcze raz.
Z jednym się zgodzę i powtórzę już to jaka n osoba z rzędu, bazy są wolne ponieważ leżą na dysku, ale mam na myśli wolne względem ramu. Lecz co w przypadku gdy mamy w RAM'ie trzymać 700GB danych? które przedsiębiorstwo zgodzi się na zakup clustra ( nie wspomnę o kwotach np. SQL Server i kosztach licencji wyliczanej na podstawie ilości wątków serwera ).
Są już tanie płyty główne w których można zamontować 500GB RAM. Są, czy nie ma, znowu kwestia wymagań i założeń, u mnie jest założenie, że dane mogą zmieścić się w RAM maszyny/klastra.
Ale nie wykluczam że za kilkanaście lat takie rozwiązanie nie będzie jednym z lepszych, bo może się okazać że 4TB ram to będzie standard, póki co.. daj sobie spokój, bo sam nawet w kilka lat nie napiszesz nic lepszego od SQLLite.
Myślę, że 16TB ram i 16 procesorów niedługo będzie łatwo osiągalne na jednej płycie głównej.
Poza tym znam kilka mechanizmów takich jak ARRAY_DML + CacheUpdates dzięki którym dopiszesz setki tysięcy rekordów w bardzo krótkim czasie.
I jeszcze tak napomnę, SELECTY są zazwyczaj wolne gdy wykonujesz w nich podzapytania,
Myślę że masz rację, ale to by też trzeba porównywać z takim programikiem w C++ który prawie teoretycznie wykorzystuje zasoby maszyny. No i jeszcze co innego gdy mówimy o zapytaniach na dyskach talerzowych, raidach, dyskach SSD i danych całkowicie zbuforowanych w RAM. Jeszcze co innego gdy w tle inny proces zrobi UPDATE. Może też by się okazalo, że narzut bazy na pod-zapytania wynosi tylko 30 razy ?
Myslę że masz rację że są wolne i że to są większe narzuty niż 30 razy, ale głowy uciąć bym sobie nie dał za to. Mogę o flaszkę sie założyć.
dodatkowo działa jakiś trigger no i łączysz pewne tabele ze sobą relacyjnie, jeżeli chcesz szybko wyświetlać dane w jakimś gridzie, to nie wyświetlaj od razu 1 000 000 rekrów, tylko rozłóż to na paczki, ograniczające się do zasięgu widoczności grida czy tam jakiegoś view. Bo po co komu wczytać wszystko skoro i tak tego nie zauważy.
Tak, te podstawowe zasady optymalizacji raczej ogarniam. Nie ogarniam szczególików konfiguracji baz danych.
Może warto byłoby zagłębić się w poznanie jakiś mechanizmów/sztuczek programistycznych jak krytykować "wolne systemy"
Może warto, ale o jakie mechanizmy programistyczne chodzi? API Postgresa do pisania pluginów i swoich procedur? Czemu nie, ale to
też są pracochłonne rozwiązania.
( sam kiedyś narzekałem na pewne rozwiązanie zwane FireDac, okazało się że moje problemy były spowodowane nieznajomością tego mechanizmu, zagłębienie się w manuale pomogło mi zrozumieć moje błędy i zmusiło do refleksji oraz rachunku sumienia ).
Pewnie, każdy w swoim życiu przez to przechodził :)
</quote> Liczy centroidy obiektów i odległość centoidy od kamery. Potem chyba kd-tree i wybiera tylko obiekty w pobliżu kamery.Co do tego zasięgu widzenia, coś takiego stosują silniki gier, nie pamiętam fachowej nazwy tego mechanizmu, ale obiekty zasłonięte przez inne nie są po prostu renderowane i GPU nie oblicza ich vertexów i pixeli, a przecież nikt i tak tego nie zauważy. Pozdrawiam P.
Pozdrawiam również.
- Rejestracja:około 21 lat
- Ostatnio:około 2 miesiące
- Postów:1082
artur_bredzki napisał(a):
Przepraszam, wideo teraz nie mogę obejrzeć. Ale to co piszesz o zbiorze roboczym, nie musi być prawdą. Musi być spełnionych kilka warunków i bazy nadają się do przechowywania zbioru roboczego, te warunki to:
- baza posiada i wykorzystuje odpowiednie indeksy do danego zadania
- jest wystarczająca ilość ram
- narzut na transfer i parsowanie zapytań nie jest problemem.
Jeśli te warunki są spełnione, to co jest problemem aby przechowywały zbiór roboczy?
Zależy co dla kogo jest "zbiorem roboczym" i jak ów zbiór będzie przetwarzany. To co nie musi być prawdą na twoim podwórku, na moim jest aksjomatem - i vice versa. Za dużo "wydaje mi się", a za mało pokory w twoich wypowiedziach, ale do rzeczy...
Osobiście mam taki problem, gdzie jest pewien zbór roboczy przechowujący od kilkuset to kilkudziesięciu tyś. obiektów biznesowych.
Jedna instancja takiego obiektu, przekłada się na (i tu zależy) od kilkudziesięciu do nawet kliku tysięcy wierszy w bazie danych rozsianych w ok. 9 tabelach.
Wymagany czas odpowiedzi (oczywiście nie samej bazy danych, a cała aplikacja ma reagować w tym czasie - a tam jeszcze sporo rysowania jest :/) to powiedzmy 200ms, do max 500ms.
I problemem nie jest odczyt a zapis danych oraz wymagana reaktywność całego systemu. Główny myk polega na tym, że obiekty biznesowe są non-stop zmieniane (w skrajnych przypadkach - średnio każdy obiekt roboczy może być dotknięty zmianą co ok. 30s) i sporo się dzieje pod spodem (obliczenia i aktualizacji innych obiektów biznesowych, które są logicznie powiązane z obiektem zmienionym).
Także rozwiązanie oparte w całości o bazę danych (i tylko o bazę danych) nie za bardzo nadaje się do tego zastosowania głównie przez pkt 1). Właśnie dlatego, że indeksy są (bo muszą), czas aktualizacji danych rośnie i zaczyna to być wąskie gardło, którego nie przeskoczę. To oczywiste.
Drugim wąskim gardłem to coraz bardziej zawiła i skomplikowana logika, a wykonanie jej wprost przez bazę danych (np. StorProc) tak naprawdę niewiele daje, poza problemami z utrzymaniem (bo oczywiście, co instalacja to trochę inna logika).
Tylko dlatego, że dokładnie wiem co robię (aktualizacja danych dotyka dokładnie tych tabel i tych pól, które zostały zmienione; proszę się nie śmiać, ale niektóre DAL są durnowate pod tym względem i aktualizują wszystko jak leci) i zbiór roboczy to de-facto obiektu w pamięci programu to baza daje rade, jeszcze...
Póki co, ale już wiem że doszedłem do ściany i dalej nie da się tego w sensowny sposób skalować. Jasne, mogę powiedzieć klientowi "dokup Pan nowszy/więcej serwerów", ale nie o to chodzi - bo tego się po prostu nie da sprzedać przy takich założeniach. A poza tym mierzi mnie taka argumentacja ;-)
Natomiast to nie baza danych jest moim głównym problemem, a potrzeba napisania proof-of-concept swego czasu, który przekształcił się w rozwiązanie produkcyjne. Jako że prrof się sprawdził, to teraz trzeba zebrać doświadczenia i napisać to inaczej. Zupełnie inaczej.
Tylko ja zbierałem produkcyjne doświadczenia co do tego systemu przez 3 lata i nie wyciągam takich wniosków na podstawie testów podobnych do twojego :D

- Rejestracja:prawie 20 lat
- Ostatnio:dzień
artur_bredzki napisał(a):
Wibowit napisał(a):
artur_bredzki napisał(a):
Może dodam jeszcze parę słów. Mam jakąś bazę danych i zapytanie. Wysyłam zapytanie do bazy, mierzę czas. Co mogę zrobić dalej? Mogę przy pomocy narzędzi i opcji bazy danych ten czas poprawić. W momencie gdy już nic nie pomaga, co można zrobić jeszcze? Mogę wierzyć że baza danych działa szybko lub wolno, albo mogę napisać właśnie taki minimalistyczny program i porównać czasy. Gdy zauważę, że baza danych działa 10 razy wolniej, to myślę sobie, baza osiąga bardzo dobry wynik. Gdy widzę że baza działa 30, a nawet 100 razy wolniej, to myślę, że nie jest najgorzej. Ale gdy widzę że baza działa 1000 razy wolniej, to zapala mi się czerwone światełko i myślę, że pomimo ogromu rzeczy jakie baza musi dodatkowo zrobić, coś jest nie tak z bazą, albo że próbuję bazie zlecić zadanie do którego się ona nie nadaje.
Najpierw zastanów się co porównujesz. Ja spojrzałem na http://4programmers.net/Forum/1275173 z http://4programmers.net/Forum/1275261 i z szybkich oględzin wyszły mi takie różnice:
- w pg masz id jako bigint, a nie int,
- w pg masz dodatkowe pola w tabeli których nie ma w c++,
- w pg sortujesz po id (order by id),
- w pg masz dodatkowy warunek na id, którego nie ma w c++,
- w pg masz inną kolejność warunków (najpierw sprawdzanie
=
, potem sprawdzniein
),- przede wszystkim, w pg robisz
select * from
zamiastselect sum(val) from
- a więc na podstawie danych w tabeli tworzysz efektywnie nową tabelę z wierszami z podstawowej, zamiast po prostu policzyć jedną wartość,Opisałem już wcześniej co w związku z tym wszystkim.
- w pg masz id jako bigint, a nie int,
Różnica pomijalnie mała w zrgubnych testach, a na komputerze 64 bitowym może bigint nawet szybciej działać.- w pg masz dodatkowe pola w tabeli których nie ma w c++,
Tak mam, ale istnieje pewien rodzaj optymalizacji w wyniku której ilość kolumn na które nie jest założony żaden warunek nie powinna rzutować na czas zapytania. Słyszałem że ten rodzaj optymalizacji jest w postgresie zaimplementowany. Było też kilka postów o tym, co się dzieje z wydajnością gdy dochodzą inne kolumny które nie są uwzględniane w warunkach zapytania.- w pg sortujesz po id (order by id),
Pierwszy warunek przechodzi jeden rekord na N, drugi jeden na M, trzeci jeden na K. Średnio sortowaniem objęty jest jeden rekord na NxMxK. Więc czas sortowania to jakieś log 10 * (1 / NMK) * ilość wierszy - pomijalnie mały w zgrubnym teście.- w pg masz dodatkowy warunek na id, którego nie ma w c++,
Dochodzi do tego warunku z prawdopodobieństwem 1 / (NMK) - czas pomijalnie mały w zgrubnym teście.- w pg masz inną kolejność warunków (najpierw sprawdzanie
=
, potem sprawdzniein
),
Czas pomijalnie mały, ponieważ każdy warunek odrzuca bardzo dużo rekordów. Poza tym słyszałem, że bazy same potrafią zmienić kolejność warunków, tak aby zacząć od warunku który odrzuca najwięcej rekordów.- przede wszystkim, w pg robisz
select * from
zamiastselect sum(val) from
- a więc na podstawie danych w tabeli tworzysz efektywnie..
Przede wszystkim w postgresie mam indeksy, a w programie ich brak. Jak już pisałem, program został napisany tak, aby jego napisanie zajęło mało czasu i jednocześnie aby na jego podstawie dało się oszacować czas zapytania z sub-optymalnymi indeksami. Program nie ma na celu odtworzenia algorytmu który wykonuje baza danych z dokładnością jeden do jeden - czemu to nie jest oczywiste?! Program wykonuje pewną operację na 20mln rekordów metodą fullscan. Drobiazgi zostały pominęte. Ta operacja zajmuje określoną ilość czasu. Z tego czasu z kolei można oszacować ile czasu trwałoby takie zapytaneie gdyby program miał indeksy. Jako że baza ma potencjalnie większą funkcjonalność, oszacowany czas należy jeszcze pomnożyć przez jakąś stałą wartość. Dopiero wtedy porównywanie ma sens i do takiego porównywania powstał ten program. Jeśli myslisz, że chcę porównywać jeden do jeden, to masz mnie za idoitę.
Skoro tak doskonale wiesz co postgres robi pod maską to po co nas w ogóle pytasz skąd są spowolnienia? Powinieneś to wykminić od razu i nam pojaśnić.
Program w C++ przetestowany przez fasadina skanuje u niego pamięć z prędkością 10 GB/s. Ty twierdzisz, że wielokrotne rozepchanie struktury danych (dodatkowymi polami) nie wpłynie na szybkość zapytania. Rozumiem, że przepustowość RAMu jest z gumy, tak?
Twoje rozumowanie jest absurdalne: "skoro z bazy dostaję mało danych to mogę w zapytaniu robić cuda na kiju i nie może to nic spowolnić". Niestety, tak to nie działa.
Odrób zadanie domowe i sprawdź czy twoje wyobrażenia mają jakikolwiek związek z rzeczywistością. Przejdź punkt po punkcie i sprawdź, czy:
- zmiana biginta na inta coś poprawi,
- wywalenie nadmiarowych pól coś poprawi,
- wywalenie sortowania coś poprawi,
- wywalnie warunku na id coś poprawi,
- zmiana kolejności warunków coś poprawi,
- wyciąganie pojedynczej sumy zamiast wielu wierszy coś zmieni,
- zrobienie wszystkich powyższych zmian coś poprawi,
- etc
- Rejestracja:około 21 lat
- Ostatnio:około 2 miesiące
- Postów:1082
Deltech napisał(a):
Poza tym znam kilka mechanizmów takich jak ARRAY_DML + CacheUpdates dzięki którym dopiszesz setki tysięcy rekordów w bardzo krótkim czasie.
No toś trafił, bo akurat na tym się "trochę" znam ;-)
I od razu będzie kontra - ARRAY_DML
znakomicie przyspiesza operacje batchowe. Prawda, ale nie każda baza danych to wspiera...
CacheUpdates znakomicie przyspiesza edycję danych przez aplikację, ale baza danych tu nic nie ma do gadania z oczywistych względów. Po prostu wszystkie zmiany są buforowane na kliencie i wysyłane jako ciąg poleceń DML - ale to nie jest ARRAY_DML
.
A więc aktualizacja danych z CachedUpdates
, mechanizm ARRAY_DML
nie jest używany, trzeba to sobie zrobić ręcznie :)
I jeszcze tak napomnę, SELECTY są zazwyczaj wolne gdy wykonujesz w nich podzapytania,
To zależy od bazy danych. Niektóre tego nie trawią zupełnie (np. starsze wersje FireBird) dla innych to praktycznie bez znaczenia.
dodatkowo działa jakiś trigger
STOP!
A co ma trigger do odczytu danych, bo nie rozumiem?
no i łączysz pewne tabele ze sobą relacyjnie, jeżeli chcesz szybko wyświetlać dane w jakimś gridzie, to nie wyświetlaj od razu 1 000 000 rekrów, tylko rozłóż to na paczki, ograniczające się do zasięgu widoczności grida czy tam jakiegoś view. Bo po co komu wczytać wszystko skoro i tak tego nie zauważy. Może warto byłoby zagłębić się w poznanie jakiś mechanizmów/sztuczek programistycznych jak krytykować "wolne systemy"( sam kiedyś narzekałem na pewne rozwiązanie zwane FireDac, okazało się że moje problemy były spowodowane nieznajomością tego mechanizmu, zagłębienie się w manuale pomogło mi zrozumieć moje błędy i zmusiło do refleksji oraz rachunku sumienia ). Co do tego zasięgu widzenia, coś takiego stosują silniki gier, nie pamiętam fachowej nazwy tego mechanizmu, ale obiekty zasłonięte przez inne nie są po prostu renderowane i GPU nie oblicza ich vertexów i pixeli, a przecież nikt i tak tego nie zauważy. Pozdrawiam P.
Ciężko się do tego odnieść, bo to tzw. best practices i każde programistyczne nie-dziecko powinno je znać i potrafić zastosować w praktyce.
A jak nie potrafi, to potem mamy takie wątki ;-)
- Rejestracja:prawie 9 lat
- Ostatnio:ponad 8 lat
- Postów:229
Wibowit napisał(a):
Skoro tak doskonale wiesz co postgres robi pod maską to po co nas w ogóle pytasz skąd są spowolnienia?
Ogólnie wiem, mam podstawy, a szczegółów nie znam.
Wibowit napisał(a):
Powinieneś to wykminić od razu i nam pojaśnić.
No wiesz, nie wiem czy mam ku temu odpowiednie kwalifikacje ;-)
Wibowit napisał(a):
Program w C++ przetestowany przez fasadina skanuje u niego pamięć z prędkością 10 GB/s. Ty twierdzisz, że wielokrotne rozepchanie struktury danych (dodatkowymi polami) nie wpłynie na szybkość zapytania. Rozumiem, że przepustowość RAMu jest z gumy, tak?
Nie twierdzę nic takiego co powyżej napisałeś. Chodziło o to, że istnieje technika optymalizacyjna, dzięki której, jak to nazywasz, rozepchane struktury nie wpływają mocno na czas wykonania zapytania. Słyszałem, że tę technikę optymalizacyjną postgres ma, ale prosty eksperyment wykazuje, że w postgresie czas rośnie wraz z dodaniem kolejnych pól do struktury/tabeli. Widzisz, ja właśnie nie znam szczegółów, może jakiejś opcji w postgresie nie umiem włączyć, aby zadziałała ta technika? O jaką technikę chodzi? Otóż technika ta nadaje się do optymalizacji sekwencyjnych odczytów danych na nośnikach takich ja dysk talerzowe, dyski ssd, macierze raid, pamięć ram. Technikę tę opisywałem już na tym forum, ale powtórzę. W przypadku gdy dane są w pamięci RAM, np. mogą to być dane zbuforowane przez bazę danych, to technika ta polega na zamianie tablicy struktur, na strukturę tablic. Bez tej techniki kolejne pola umieszczamy jako kolejne składowe w strukturze, np.:
struct Record {
int a;
double b;
char c[16];
itd;
}
Potem budujemy tablicę z tej struktury:
Record records[rozmiar];
Z tą techniką w strukturze umieszczamy tablice:
struct Table {
int a[rozmiar];
double b[rozmiar];
char c[rozmiar][16];
itd[rozmiar];
};
W momencie gdy warunek nakładamy tylko na pole 'a', ilość pozostałych pól nie ma najmniejszego znaczenia. Nie trzeba zwiększać przepustowości pomiędzy ram a cache. Gdy tę technikę chcemy zastosować na dysku, to jedną tablę z kilkoma polami, rozbijamy na wiele tabel z jednym polem.
Wibowit napisał(a):
Twoje rozumowanie jest absurdalne: "skoro z bazy dostaję mało danych to mogę w zapytaniu robić cuda na kiju i nie może to nic spowolnić". Niestety, tak to nie działa.
Zapewniam Cię, że nigdy takiego rozumowania nie przeprowadzałem. Jeśli myślisz że tak rozumuję, to nie zrozumieliśmy się w czymś.
Wibowit napisał(a):
Odrób zadanie domowe i sprawdź czy twoje wyobrażenia mają jakikolwiek związek z rzeczywistością. Przejdź punkt po punkcie i sprawdź, czy:
- zmiana biginta na inta coś poprawi,
Zbyt mały potencjalny zysk, nie będę nawet próbował. Poza tym musi zostać bigint.
Wibowit napisał(a):
- wywalenie nadmiarowych pól coś poprawi,
W poprzednim wątku dodawałem pola. Po dodaniu dużej ilości dodatkowych pól czas wzrósł prawie 2 krotnie.
Wibowit napisał(a):
- wywalenie sortowania coś poprawi,
Hmmm, jeśli poprawi lub nie poprawi to jakie wnioski z tego będzie można wyciągnąć?
Wibowit napisał(a):
- wywalnie warunku na id coś poprawi,
Chyba nie będę tego sprawdzał, warunek na ID jest niezbędny i w tym wariancie zapytania i we wszystkich innych wariantach. Poza tym nie mam właściwego indeksu na ten wariant zapytania bez id, nie wiem jakie wnioski z tego można będzie wyciągnąć, wyjaśnisz mi?
Wibowit napisał(a):
- zmiana kolejności warunków coś poprawi,
W sumie ciekawy pomysł na test, to sprawdzę.
Wibowit napisał(a):
- wyciąganie pojedynczej sumy zamiast wielu wierszy coś zmieni,
Sprawdzałem, nie ma istotnego wpływu.
Wibowit napisał(a):
- zrobienie wszystkich powyższych zmian coś poprawi,
Najbardziej podoba mi się test ze zmianą kolejności warunków. Dowiem się, czy baza sama optymalizuje kolejność, czy nie. Ciekawe czy w postgresie jakąś opcją można tę optymalizację włączyć lub wyłączyć, i czy można tę optymalizację włączyć dla pojedynczych zapytań, czy tylko globalnie dla całej bazy?
Edit:
Sprawdziłem 3 różne kolejności warunków and na 10 zapytaniach. Najszybsza kolejność działa 2 razy szybciej niż najwolniejsza. Wniosek: postgres tego sam z automatu nie optymalizuje - przynajmniej z moją konfiguracją i z moimi statystykami.
Czyżby to samopiszący się temat?
Baza danych czy nie baza.
Można napisać prosty algorytm, który przeleci każdą literę jak i-węzeł tablic każdej litery, aż do zbioru wartości indeksów, odpowiadających zbiorowi przybliżonemu im więcej liter tym mniejsze prawdopodobieństwo powtórzenia.
I potem wielkość tabeli * index = miejsce w pamięci.
No ale takie rozwiązanie przygotowawcze zabierze dużo cykli procesora no i kupe pamięci.
Później można to zapisać i przy dodawaniu dopisywać do odpowiedniej tablicy indeks danych i do bazy wszystkie dane.
Ale za to raczej będzie najszybsze na bardzo dużych ilościach danych.
Ale ilość zajętej pamięci będzie równa = baza danych+ litery alfabetuilość poziomówstruktura listy + ilość indeksów bazy * maksymalna_ilość_struktur.
Potem to tylko się przeszuka ostatnią tablice indeksów w poszukiwaniu wybranej frazy.
Dzięki temu będzie można wyliczyć, który sektor bazy danych wczytać do pamięci.
Ale takie coś rozwiąże wyszukiwanie po alfabecie i po indeksie.
Do tego prawa dostępu jakiś język interpretowany, dodatkowo interface sieciowy.
No i dochodzą innego typu dane do wyszukiwania, przelecenie całej bazy będzie długie, więc też posortowanie według jakiegoś czynnika.
Ale też wypadało by to zrobić wcześniej bo tak to w jednej chwili nie ogarnie.
Chyba, że na małej ilości danych.
Albo z dobrym algorytmem dzielenia i rządzenia.
Lecz użyty drugi raz będzie szybszy niż przy pierwszym.
- Rejestracja:ponad 9 lat
- Ostatnio:około miesiąc
- Postów:105
wloochacz napisał(a):
Deltech napisał(a):
Poza tym znam kilka mechanizmów takich jak ARRAY_DML + CacheUpdates dzięki którym dopiszesz setki tysięcy rekordów w bardzo krótkim czasie.
No toś trafił, bo akurat na tym się "trochę" znam ;-)
I od razu będzie kontra -ARRAY_DML
znakomicie przyspiesza operacje batchowe. Prawda, ale nie każda baza danych to wspiera...
CacheUpdates znakomicie przyspiesza edycję danych przez aplikację, ale baza danych tu nic nie ma do gadania z oczywistych względów. Po prostu wszystkie zmiany są buforowane na kliencie i wysyłane jako ciąg poleceń DML - ale to nie jestARRAY_DML
.
A więc aktualizacja danych zCachedUpdates
, mechanizmARRAY_DML
nie jest używany, trzeba to sobie zrobić ręcznie :)I jeszcze tak napomnę, SELECTY są zazwyczaj wolne gdy wykonujesz w nich podzapytania,
To zależy od bazy danych. Niektóre tego nie trawią zupełnie (np. starsze wersje FireBird) dla innych to praktycznie bez znaczenia.
dodatkowo działa jakiś trigger
STOP!
A co ma trigger do odczytu danych, bo nie rozumiem?
Ups.. Pisałem o jednym myślałem o drugim, jeżeli chodzi o te triggery, zamiast + powinien być OR, uchylam czoło, już precyzuję.
Mianowicie są szczególne przypadki gdzie tworzy się Tabele na potrzebę kopiowania jakiś danych i z jakiejś przyczyny pewne pola są błędne ( głupota programisty/admina ), więc przychodzi czas na napisanie pewnego update który to korzysta z selecta a ten natomiast jest mega bardzo skomplikowanym selectem który zajmuje sobie dużo linijek bo zawiera masę relacji, grupowań i innych skrzatów. Dodamy do tego że wcześniej przyszła nam jakaś tam rzecz do głowy i założyliśmy na tabelę trigger, który będzie logował zmiany czy coś takiego,
no i proszę mamy to :-) Jak zwykle rzucam na prawo i lewo skrótami myślowymi, trzeba mnie czasem za jęzor pociągnąć, niż zastanawiać się i denerwować co autor miał na myśli. Przecież to nie lekcja polskiego
Co do Array_DML + CacheUpdates, bardziej miałem na myśli te kroki "optymalizacyjne" jeżeli możemy je tak nazwać :D jak łączenie tego w całość.
- Rejestracja:prawie 9 lat
- Ostatnio:ponad 8 lat
- Postów:229
artur_bredzki napisał(a):
Wibowit napisał(a):
Skoro tak doskonale wiesz co postgres robi pod maską to po co nas w ogóle pytasz skąd są spowolnienia?
Ogólnie wiem, mam podstawy, a szczegółów nie znam.
Wibowit napisał(a):
Sprawdziłem 3 różne kolejności warunków and na 10 zapytaniach. Najszybsza kolejność działa 2 razy szybciej niż najwolniejsza. Wniosek: postgres tego sam z automatu nie optymalizuje - przynajmniej z moją konfiguracją i z moimi statystykami.
Odpowiem sam na swoją wypowiedź, bo to rodzaj sprostowania.
Po teście coś mnie zaniepokoiło. Mianowicie, zadalem sobie pytanie, dlaczego kolejność warunków miałaby wpływać na szybkość wykonania zapytania, skoro jest założony indeks b-tree? Zrobiłęm więcej testów na bazie uproszczonej i na pełnej. Okazało się, że na bazie uproszczonej praktycznie nie ma różnicy. Na pełnej jest różnica, niewiele mniejsza niż 2 razy. Zatem nie tylko nic się nie nauczyłem, ale mam jeszcze większy mętlik :)

- Rejestracja:prawie 18 lat
- Ostatnio:około godziny
no to wrzuć dane do np redisa, który trzyma dane w ramie, a np co jakiś czas zrzucaj to na dysk, aby przyśpieszyć odczyt/zapis Twojej aplikacji.
Trzymanie w ramu ma jeden zasadniczy minus - padnie serwer/prądu brak i dane, które tam trzymasz znikają praktycznie bezpowrotnie.
Same bazy danych są dość szybkie, dość dużym wąskim gardłem wg mnie mogą być:
- źle zaprojektowane tabele/struktura
- brak/złe indeksy w tabelach
- fakt, że trzeba z dysku odczytywać/zapisywać dane, co jest definitywnie wąskim gardłem
Obwinianie bazy danych za to, że są wolne wg mnie mija się z celem, bo one same w sobie mogą być bardzo wydajne, a spowolnienie może być spowodowane czymś innym.
- Rejestracja:prawie 9 lat
- Ostatnio:ponad 8 lat
- Postów:229
no_solution_found napisał(a):
no to wrzuć dane do np redisa, który trzyma dane w ramie, a np co jakiś czas zrzucaj to na dysk [...]
Resis to swietna baza RAM, sama zrzuca dane na dysk. Ciekawe czy byłby szybszy od RDBMS w przypadku gdy RDBMS ma dane i indeksy całkowicie zbuforowane w RAM.

- Rejestracja:prawie 10 lat
- Ostatnio:5 miesięcy
- Lokalizacja:Hong Kong
tak mnie zastanawia (byc moze cos mi umknelo) czemu juz pierdyliard razy wspomniales o tym 'calkowitym buforowaniu danych w ramie' (juz kultowe sie to staje, przynajmniej dla mnie). co tak naprawde robi ten twoj system? wierz mi lub nie ale nawet w systemach hft gdzie milisekunda to wiecznosc (i potencjalne milionowe straty) nie trzyma sie wszystkich danych w pamieci, mimo ze przecietny bank inwestycyjny jest w stanie wydac calkiem sporo na sprzet jesli tylko jest to uzasadnione.
- Rejestracja:prawie 9 lat
- Ostatnio:ponad 8 lat
- Postów:229
katelx napisał(a):
tak mnie zastanawia (byc moze cos mi umknelo) czemu juz pierdyliard razy wspomniales o tym 'calkowitym buforowaniu danych w ramie' (juz kultowe sie to staje, przynajmniej dla mnie). co tak naprawde robi ten twoj system? wierz mi lub nie ale nawet w systemach hft gdzie milisekunda to wiecznosc (i potencjalne milionowe straty) nie trzyma sie wszystkich danych w pamieci, mimo ze przecietny bank inwestycyjny jest w stanie wydac calkiem sporo na sprzet jesli tylko jest to uzasadnione.
Generalnie dlatego, że piszę w skórcie. Oczywiście że chodzi o przechowywanie w pamięci ram tylko tego co ważne dla wydajności. Ale zobacz ile już jest nieporozumień. Jakby ta rozmowa wyglądała, gdybym zaczął mieszać w to wszystko kolejne szczegóły? Potem będę się zastanawiał jakie są możliwości baz danych pod względem precyzyjnego wskazania co powinno być buforowane, a co. Nie chcę dodatkowo skomplikować rozmowy - to jedna sprawa.
Druga sprawa jest taka: jaki sens porównywania bazy która trzyma jakąś częsć danych na dysku z bazami rypu Redis - a o tym była właśnie mowa w poprzednim poście.
- Rejestracja:prawie 9 lat
- Ostatnio:ponad 8 lat
- Postów:229
katelx napisał(a):
zadalam ci pytanie i nie rozumiem czemu unikasz odpowiedzi. co takiego robi twoj system ze z kilkoma milionami rekordow nie wyrabiasz wydajnosciowo i cudujesz?
Bo to nie ma znaczenia. Zapytanie albo wyrabia na tabeli w której jest kilka kolumn typu int, albo nie wyrabia. Czy te inty będą spisem części rowerowych, spisem paragonów ze sklepu spożywczego - nie ma znaczenia dla wydajności.
Shalom