2012-11-07 29 views
5

Tôi cần một số mẹo để tối ưu hóa truy vấn tìm nạp từ các bảng lớn.Tối ưu hóa truy vấn PostgreSQL với nhiều lần tham gia, sắp xếp theo và giới hạn nhỏ

Trong ví dụ này tôi có 5 bảng:

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 

Tôi cần một truy vấn với danh sách có thứ tự các cổ phiếu, hạn chế, vì vậy đây là cách tiếp cận chung tôi đã sử dụng:

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 

này hoạt động nhanh trên các bảng nhỏ, nhưng khi các bảng phát triển truy vấn trở nên rất tốn kém. Với 3,5M hàng trong kho, 300K trong Prod_attributes, 25K Sản phẩm nó thực thi trong hơn 8800ms, điều này không thể chấp nhận được đối với tôi.

Tất cả khóa forgein có chỉ mục và DB đã được phân tích chân không gần đây.

Tôi biết rằng vấn đề nằm trong phần ORDER BY, vì truy vấn không sử dụng chỉ mục và quét tuần tự. Nếu tôi xóa thứ tự thì truy vấn rất nhanh.

Để giải quyết điều này, tôi biết tôi có thể xóa ORDER BY, nhưng đó không phải là tùy chọn khả thi đối với tôi. De-bình thường hóa của DB hoặc quan điểm vật hoá có thể giúp ở đây cũng - một lần nữa tôi muốn tránh điều này nếu có thể.

Tôi có thể làm gì khác để tăng tốc truy vấn này?

GIẢI THÍCH PHÂN TÍCH:
- chậm với thứ tự theo: http://explain.depesz.com/s/AHO
- nhanh chóng mà không cần theo thứ tự theo: http://explain.depesz.com/s/NRxr

+0

Bạn có chỉ mục theo thứ tự theo cột không? –

+0

Xin chào, vâng. Tôi đã thêm các chỉ mục theo thứ tự theo các cột như sau: CREATE INDEX i_p_name TRÊN sản phẩm SỬ DỤNG btree (p_name); Tôi đã thêm chúng dưới dạng các chỉ mục riêng biệt - 1 cho mỗi đơn đặt hàng theo trường. Thứ tự ASC và NULLs LAST. Không có gì thay đổi trong kế hoạch sau khi truy vấn lại. – Lucius

+0

Bạn có chạy phân tích sau khi tạo chỉ mục không? –

Trả lời

1

Một cách tốt để đi là để loại bỏ stores từ tham gia. Thay vào đó, bạn có thể:

  • Vòng qua stores (thứ tự theo s_name) trong một thủ tục lưu trữ hoặc trong mã nguồn và, cho mỗi cửa hàng, thực hiện tham gia lọc trên stocks.fk_store. Bạn có thể phá vỡ vòng lặp bất cứ khi nào bạn có đủ số lượng bản ghi.

  • Nếu có thể, hãy phân vùng stocks bằng cách sử dụng phím fk_store, để giảm số lượng bộ dữ liệu tham gia.

Bằng cách này, bạn sẽ có lợi ích tốt.

Các vấn đề liên quan