Postgresql - wydajność |
Postgresql - wydajność |
4.08.2008, 11:07:20
Post
#1
|
|
Grupa: Zarejestrowani Postów: 235 Pomógł: 2 Dołączył: 30.06.2006 Ostrzeżenie: (0%) |
Witam
Jakiś czas temu opisałem problem z ładowaniem wpisów do bazy - rozwiązaniem okazał się serwer dedykowany i podzielenie pliku na pakiety Aktualnie mierzę się z takim problemem: baza zawiera 30 mln wpisów i zwykły count zajmuje 8 sekund (tak, wiem, w postgresqlu są wolne, ale bez przesady!). Jak można rozwiązać problem wydajności przy tej ilości danych? Czytałem trochę o partycjonowaniu tabel, trochę o widokach - jednak nie wiem które rozwiązanie przyniesie największe korzyści wydajnościowe. Tabela zawiera 4 kolumny - 3 integery i 1 boolean. Jeśli to ma znaczenie: wyszukiwanie w niej planowo ma się opierać na czymś takim: WHERE col1 = 5 AND col2 BETWEEN 400 AND 94200 |
|
|
4.08.2008, 15:10:22
Post
#2
|
|
Grupa: Zarejestrowani Postów: 793 Pomógł: 32 Dołączył: 23.11.2006 Skąd: Warszawa Ostrzeżenie: (0%) |
A kiedy miałeś ostatnio VACUUM na niej robione?
Co do wyszukiwania to indeks dwukolumnowy w takim przypadku musi być typu btree. Ale niech ktoś jeszcze lepiej się znający może wypowie. Co do count to jakoś tak dziwnie, skoro u mnie tsearch2 w ~200k krotkach każda po kilka kilo tekstu wyszukiwał na normalnym kompie w ciągu milisekund. Spróbuj count(1) działa szybciej, powinien być paru krotnie szybszy. -------------------- Algorytmy w PHP, czy ktoś o tym słyszał?
Dlaczego tak mało kobiet programuje? ponieważ nie zajmują się głupotami. |
|
|
4.08.2008, 15:19:02
Post
#3
|
|
Grupa: Zarejestrowani Postów: 235 Pomógł: 2 Dołączył: 30.06.2006 Ostrzeżenie: (0%) |
Dzięki za odpowiedź
VACUUM - dzisiaj całą bazę postawiłem i uzupełniłem ją danymi, potem zrobiłem VACUUM FULL. Typ indeksu - ok, dzięki, zmienię (mam nadzieję że da się bez czyszczenia tabeli ) i sprawdzę wyszukiwanie ponownie. co do count(1) - nie wiedziałem nawet, dzięki niestety nie zmienia zbyt wiele :/ Kod portal=# explain analyze select count(1) from table; QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------- Aggregate (cost=495164.33..495164.34 rows=1 width=0) (actual time=8134.547..8134.547 rows=1 loops=1) -> Seq Scan on table (cost=0.00..426028.26 rows=27654426 width=0) (actual time=0.009..4575.271 rows=27654426 loops=1) Total runtime: 8134.594 ms (3 rows) portal=# explain analyze select count(*) from table; QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------- Aggregate (cost=495164.33..495164.34 rows=1 width=0) (actual time=8023.854..8023.855 rows=1 loops=1) -> Seq Scan on table (cost=0.00..426028.26 rows=27654426 width=0) (actual time=0.013..4521.300 rows=27654426 loops=1) Total runtime: 8023.903 ms (3 rows) Dziwi mnie taki rezultat, szczególnie że komputer to nie taki słaby serwer dedykowany ze świeżo postawionym systemem. Zgodnie ze wskazówkami z wiki postgresqla zmieniłem mu limity pamięci ale to również nie pomogło. Całość jest na Ubuntu server 8.04 na ReiserFS - wcześniej był umieszczony na ext3 i był identyczny problem. =========EDIT========== Indexes: "table_pkey" PRIMARY KEY, btree (id) CLUSTER Czyli porządany typ już jest. Pozostałe dwie kolumny numeryczne to po prostu klucze obce. Ten post edytował Ziels 6.08.2008, 17:10:21 |
|
|
4.08.2008, 15:37:59
Post
#4
|
|
Grupa: Zarejestrowani Postów: 793 Pomógł: 32 Dołączył: 23.11.2006 Skąd: Warszawa Ostrzeżenie: (0%) |
indeks na te kolumny:
Wyszukiwanie praktycznie nie widoczne. -------------------- Algorytmy w PHP, czy ktoś o tym słyszał?
Dlaczego tak mało kobiet programuje? ponieważ nie zajmują się głupotami. |
|
|
4.08.2008, 16:00:08
Post
#5
|
|
Grupa: Zarejestrowani Postów: 235 Pomógł: 2 Dołączył: 30.06.2006 Ostrzeżenie: (0%) |
Zadziałało - dzięki wielkie Szukanie takie o którym pisałem działa tak jak powinno
A nie wiesz może jak tego counta na całości przyspieszyć? Mógłbym zrobić osobną tabelę na county i triggerem to załatwić ale zawsze zostaje kwestia warunków. |
|
|
4.08.2008, 16:36:02
Post
#6
|
|
Grupa: Zarejestrowani Postów: 793 Pomógł: 32 Dołączył: 23.11.2006 Skąd: Warszawa Ostrzeżenie: (0%) |
=========EDIT========== Indexes: "table_pkey" PRIMARY KEY, btree (id) CLUSTER Czyli masz CLUSTER założony na index na id? Jeśli tak, to trochę to bez sensu jest ;] Co do count(*) to u mnie (normalny komp 3gb ram'u) zajmuje 11-12s (na 30milionach krotek o takim samym rodzaju jak Twoje) Co do count, poczytaj: http://www.varlena.com/GeneralBits/120.php http://wiki.postgresql.org/wiki/Slow_Counting może coś wybierzesz. Ale ogólnie jeśli w większości zapytań z count, ogranicza się do małego zbioru wyników, to nie będzie to takie obciążające. A zapomniałem o tym, że PostgreSQL ma już optymalizację, i count(*) działa na innych zasadach niż w niektórych bazach, więc "trik" z 1 nie działa już. -------------------- Algorytmy w PHP, czy ktoś o tym słyszał?
Dlaczego tak mało kobiet programuje? ponieważ nie zajmują się głupotami. |
|
|
4.08.2008, 19:32:18
Post
#7
|
|
Grupa: Zarejestrowani Postów: 235 Pomógł: 2 Dołączył: 30.06.2006 Ostrzeżenie: (0%) |
Dzięki
To ja moze jeszcze skorzystając z tego że założyłem temat dopytam - jak sobie poradzic z zapytaniami zwracającymi dużo rekordów przy tej ilości danych? przykładowe zapytanie:
test1 - 22 tys. wpisów test2- 13 tys. wpisów test2_in_test1 - 30 mln wpisów test3 - 40 tys wpisów Z czego każdy rekord z test1 może mieć około 7 tysięcy zaleznosci w tabeli łączącej. Zapytanie przedstawione powyżej jest niesamowicie wolne - co polecacie żeby sobie z tym poradzić? Czytałem o Materialized view - wydaje mi się że to mogło by znacznie przyspieszyć działanie. Dalej - może jakieś partycjonowanie bazy? Ten post edytował Ziels 4.08.2008, 19:35:30 |
|
|
4.08.2008, 21:39:16
Post
#8
|
|
Grupa: Zarejestrowani Postów: 793 Pomógł: 32 Dołączył: 23.11.2006 Skąd: Warszawa Ostrzeżenie: (0%) |
Proste pytanie, czy jest konieczne aby tyle danych na raz zostało zwróconych?
-------------------- Algorytmy w PHP, czy ktoś o tym słyszał?
Dlaczego tak mało kobiet programuje? ponieważ nie zajmują się głupotami. |
|
|
6.08.2008, 13:29:38
Post
#9
|
|
Grupa: Zarejestrowani Postów: 235 Pomógł: 2 Dołączył: 30.06.2006 Ostrzeżenie: (0%) |
Nie - zwykle to będą "paczki" maksymalnie po 100 wierszy, ale przy takim zapytaniu z joinami ustawienie limitu na 10 nic nie da bo i tak musi przeszukać całą tabelę, zrobić łączenia i zajmuje to strasznie dużo czasu.
Stworzyłem zmaterializowany widok żeby troche czasu zaoszczędzić na łączeniu tabel - ale nawet przy takim rozwiązaniu wykonanie zapytania trwa kilkanaście sekund - czyli czas nie do zaakceptowania. Nie masz może jakiegoś pomysłu na to? ===EDIT=== spróbuję założyć indeks na ten widok Ten post edytował Ziels 6.08.2008, 13:31:42 |
|
|
6.08.2008, 14:28:59
Post
#10
|
|
Grupa: Zarejestrowani Postów: 793 Pomógł: 32 Dołączył: 23.11.2006 Skąd: Warszawa Ostrzeżenie: (0%) |
Chodziło mi o takie coś, czy przed złączeniem nie możesz przefiltrować jednej z tabel i do niej dołączyć resztę danych, czy potrzebujesz złączonych tabel, aby móc wybrać te potrzebne?
P.S. Czytałeś http://jonathangardner.net/tech/w/PostgreS...erialized_Views EDIT co do indeksu, to zrób tylko to porządnie Aby z nich korzystało (zawsze sprawdzaj) Ten post edytował Sedziwoj 6.08.2008, 14:30:16 -------------------- Algorytmy w PHP, czy ktoś o tym słyszał?
Dlaczego tak mało kobiet programuje? ponieważ nie zajmują się głupotami. |
|
|
6.08.2008, 14:31:37
Post
#11
|
|
Grupa: Zarejestrowani Postów: 235 Pomógł: 2 Dołączył: 30.06.2006 Ostrzeżenie: (0%) |
Dokładnie tamtą stronę czytałem
Ano dokładnie - łączenie jest mi potrzebne do wybrania danych. Założenie indeksu na zmaterializowany widok (aż się zdziwiłem że tak można) załatwiło sprawę szukania - idzie błyskawicznie:) |
|
|
Wersja Lo-Fi | Aktualny czas: 18.04.2024 - 07:07 |