2012-11-07 12 views
5

Potrzebuję wskazówek, jak optymalizować zapytania pobierane z dużych tabel.Optymalizowanie zapytania PostgreSQL z wieloma złączeniami, kolejność i mały limit

W tym przykładzie Mam 5 tabel:

Brands 
- id_brand 
- b_name 

Products 
- id_product 
- p_name 
- ean 
... 
- fk_brand 

Prod_attributes 
- id_prod_att 
- size_basic 
... 
- fk_product 

Stores 
- id_store 
- s_name 
... 

Stocks 
- id_stock 
- stock_amount 
- fk_prod_att 
- fk_store 

muszę zapytać o uporządkowanej listy zasobów, ograniczone, więc jest to ogólne podejście użyłem:

SELECT stores.s_name, stocks.stock_amount, prod_attributes.size_basic, 
products.p_name, products.ean, brands.b_name 

FROM (stocks 
    INNER JOIN stores 
    ON stocks.fk_store = stores.id_store) 
    INNER JOIN (prod_attributes 
     INNER JOIN (products 
      INNER JOIN brands 
      ON products.fk_brand = brands.id_brand) 
     ON prod_attributes.fk_product = products.id_product) 
    ON stocks.fk_prod_att = prod_attributes.id_prod_att 

ORDER BY s_name, p_name, size_basic 

LIMIT 25 OFFSET 0 

To działa szybko na małych stołach, ale gdy tabele rosną, zapytanie staje się bardzo kosztowne. Z 3,5 mln rzędów w magazynie, 300 tys. W prod_attributes, 25K produktów, które wykonuje w ponad 8800ms, co jest dla mnie nie do przyjęcia.

Wszystkie klucze forgein mają indeksy, a baza danych została ostatnio zanalizowana pod kątem próżni.

Wiem, że problem leży w części ORDER BY, ponieważ zapytanie nie korzysta z indeksów i wykonuje sekwencyjne skanowanie. Jeśli usuniemy zamówienie, zapytanie jest bardzo szybkie.

W celu rozwiązania tego problemu wiem, że mogę usunąć ZAMÓWIENIE, ale nie jest to dla mnie możliwe. Oddolna normalizacja DB lub zmaterializowanego widoku mogłaby tu również pomóc - znowu chciałbym tego uniknąć, jeśli to możliwe.

Co jeszcze mogę zrobić, aby przyspieszyć to zapytanie?

EXPLAIN ANALYSE:
- slow o zamówienie przez: http://explain.depesz.com/s/AHO
- szybko, bez zlecenia przez: http://explain.depesz.com/s/NRxr

+0

Czy masz indeks na zamówienie według kolumn? –

+0

Cześć, tak. Dodałem indeksy do zamówienia według kolumn jako takich: CREATE INDEX i_p_name ON products USING btree (p_name); Dodałem je jako oddzielne indeksy - 1 dla każdego zamówienia według pola. Porządek ASC i NULL OSTATNIE. Nic się nie zmieniło w planie po ponownym uruchomieniu zapytania. – Lucius

+0

Czy uruchomiłeś analizę po utworzeniu indeksów? –

Odpowiedz

1

Możliwym sposobem jest usunięcie stores z przyłączyć. Zamiast tego, można:

  • Pętla przez stores (kolejność według s_name) w procedurze przechowywanej lub w kodzie źródłowym, a dla każdego sklepu, wykonać złączenie filtrowanie stocks.fk_store. Możesz przerwać pętlę za każdym razem, gdy uzyskasz wystarczającą liczbę rekordów.

  • Jeśli to możliwe, partycja stocks użyciu fk_store klucza, w celu zmniejszenia mocno liczbę krotek w sprzężeniu.

W ten sposób powinieneś mieć dobrą korzyść.

Powiązane problemy