Nie jestem zaznajomiony z wyświetlaniem wyników WYRAŻENIA ANALIZY, mam ogromny problem z tym, że moje zapytania są zbyt wolne. Próbowałem przeczytać, jak interpretować wyniki z wyjaśnień, ale wciąż nie wiem, czego powinienem szukać i co może być nie tak. Mam wrażenie, że gdzieś błyska jakieś duże czerwone światło, po prostu tego nie widzę.Jak rozumieć WYJAŚNIJ ANALIZĘ
Więc zapytanie jest dość proste, to wygląda to tak:
EXPLAIN ANALYZE SELECT "cars".* FROM "cars" WHERE "cars"."sales_state" = 'onsale' AND "cars"."brand" = 'BMW' AND "cars"."model_name" = '318i' AND "cars"."has_auto_gear" = TRUE LIMIT 25 OFFSET 0
a wynik takiego:
Limit (cost=0.00..161.07 rows=25 width=1245) (actual time=35.232..38.694 rows=25 loops=1)
-> Index Scan using index_cars_onsale_on_brand_and_model_name on cars (cost=0.00..1179.06 rows=183 width=1245) (actual time=35.228..38.652 rows=25 loops=1)
Index Cond: (((brand)::text = 'BMW'::text) AND ((model_name)::text = '318i'::text))
Filter: has_auto_gear"
Total runtime: 38.845 ms
Trochę tła: jestem na PostgreSQL 9.1.6, uruchamianie dedykowanych baz danych Herokus. Mój db ma około 7,5 GB RAM, samochody stołowe zawiera 3,1 mln wierszy, a około 2,0 mln wierszy ma sales_state = "onsale". Tabela ma 170 kolumn. Indeks że używa wygląda mniej więcej tak:
CREATE INDEX index_cars_onsale_on_brand_and_model_name
ON cars
USING btree
(brand COLLATE pg_catalog."default" , model_name COLLATE pg_catalog."default")
WHERE sales_state::text = 'onsale'::text;
kogokolwiek widząc jakąś wielką oczywisty problem?
Edycja:
SELECT pg_relation_size('cars'), pg_total_relation_size('cars');
pg_relation_size: 2058444800 pg_total_relation_size: 4900126720
SELECT pg_relation_size('index_cars_onsale_on_brand_and_model_name');
pg_relation_size: 46301184
SELECT avg(pg_column_size(cars)) FROM cars limit 5000;
Średnia: 636,9732567210792995
BEZ GRANIC:
EXPLAIN ANALYZE SELECT "cars".* FROM "cars" WHERE "cars"."sales_state" = 'onsale' AND "cars"."brand" = 'BMW' AND "cars"."model_name" = '318i' AND "cars"."has_auto_gear" = TRUE
Bitmap Heap Scan on cars (cost=12.54..1156.95 rows=183 width=4) (actual time=17.067..55.198 rows=2096 loops=1)
Recheck Cond: (((brand)::text = 'BMW'::text) AND ((model_name)::text = '318i'::text) AND ((sales_state)::text = 'onsale'::text))
Filter: has_auto_gear
-> Bitmap Index Scan on index_cars_onsale_on_brand_and_model_name (cost=0.00..12.54 rows=585 width=0) (actual time=15.211..15.211 rows=7411 loops=1)"
Index Cond: (((brand)::text = 'BMW'::text) AND ((model_name)::text = '318i'::text))
Total runtime: 56.851 ms
Spróbuj odkurzania - http://www.postgresql.org/docs/8.1/static/maintenance.html. Plan zapytania wygląda rozsądnie, ale czas na pewno nie! –
Tuż przed uruchomieniem zapytania uruchomiłem pełną próżnię i przeanalizowałem ... Moja strona internetowa jest wyszukiwarką używanych samochodów, więc terminy są zdecydowanie niedopuszczalne. Moim celem jest zredukowanie całkowitego czasu do mniej niż 1 sekundy. Czy uważasz, że jest to w ogóle możliwe, czy też będę musiał szukać innej technologii niż racjonalna baza danych? –
@NielsKristian Myślę, że dużą część problemu może stanowić część "170 kolumn". Jak duży jest stół? 'SELECT pg_relation_size ('cars'), pg_total_relation_size ('cars');'. Również 'SELECT pg_relation_size ('index_cars_onsale_on_brand_and_model_name');', aby uzyskać rozmiar indeksu. Jaka jest średnia szerokość wiersza? 'SELECT avg (pg_column_size (samochody)) Z limitu samochodów testowych 5000;' –