Thứ tự các cột trong một chỉ mục ghép trong PostgreSQL (và thứ tự truy vấn)


9

Tôi có một bảng với 50K hàng. Nó thực sự là một bảng PostGIS.

Truy vấn có 4 phần (1 bắt buộc) (3 Tùy chọn)

  1. hộp giao nhau (một hình chữ nhật địa lý) với 4 lat, dài (tôi sử dụng st_intersects) [Bắt buộc]
  2. Phạm vi ngày (tối thiểu, tối đa) trên trường ngày
  3. Loại tệp (một bộ tối đa 8 giá trị văn bản) hiện đang sử dụng IN (.....) nhưng tôi có thể tạo bảng tạm thời nếu cần. Tôi thấy rất nhiều người không thích IN.
  4. Quốc gia (một giá trị văn bản).

Tôi mong đợi khoảng 100 - 4.000 hàng trả lại

Nếu tôi tạo một chỉ mục ghép trên bảng, tôi nên sử dụng cột nào trước tiên. Các hạt mịn có lẽ là vị trí (dữ liệu được lan truyền trên toàn thế giới). Tôi hiện có nó là chỉ số GIST.

Các chỉ số khác sẽ là BTREE.

Trực giác của tôi nói sử dụng hạt mịn, và khóa học cuối cùng. Ví dụ: Chỉ có khoảng 12 loại tệp, vì vậy đó sẽ là các nhóm rất lớn cho chỉ mục.

Các bậc thầy về PostgreSQL và PostGIS (những người biết nội bộ của hệ thống) nói gì?


CẬP NHẬT:

Hãy để tôi làm sắc nét câu hỏi này.

  1. Tôi không muốn bất cứ ai phải làm công việc tôi nên làm. Tôi tôn trọng thời gian của bạn quá nhiều. Vì vậy, tôi sẽ nhận được để giải thích phân tích sau.
  2. Tất cả tôi đang tìm kiếm là một số gợi ý và lời khuyên và hướng dẫn.
  3. Tôi đọc bài đăng nhỏ tuyệt vời này: https://devcenter.heroku.com/articles/postgresql-indexes#managing-and-maintained-indexes về các chỉ mục
  4. Những gì tôi thường làm là tạo 4 chỉ mục riêng biệt (hộp địa lý, tên quốc gia, file_type và ngày) nhưng những gì muốn xem một truy vấn tổng hợp sẽ làm gì.

Hãy cho tôi biết nếu bất kỳ giả định nào là sai. (Tôi khá mới với ý tưởng về chỉ số ghép)

  1. Trật tự là quan trọng. Chọn làm chỉ mục đầu tiên, chỉ số sẽ cắt giảm các hàng nhiều nhất (trong trường hợp của tôi, vị trí (địa lý) là một đa giác đơn giản hoặc đa giác sẽ làm tốt nhất).
  2. Đôi khi các truy vấn sẽ bỏ qua các chỉ mục. Nhưng nếu tôi tạo một truy vấn hỗn hợp bằng khóa (# 1, # 2, # 3, # 4) thì ngay cả khi người dùng tạo thứ gì đó yêu cầu # 1, # 3, trình hoạch định vẫn sẽ sử dụng truy vấn hỗn hợp duy nhất, vì họ đặt hàng được duy trì.
  3. Thông thường tôi sẽ tạo ba truy vấn BTREE và một GIST (cho loại địa lý). PostGIS không hỗ trợ tạo ra một hợp chất từ ​​nhiều loại chỉ mục. Vì vậy, tôi sẽ phải sử dụng GIST chỉ số ghép. Nhưng điều đó không nên làm tổn thương mọi thứ.
  4. Nếu tôi tạo một số chỉ số tổng hợp hoặc giá trị đơn bổ sung, trình hoạch định đủ thông minh để chọn chỉ số thông minh nhất .....
  5. Tên quốc gia có thể có khoảng 250 giá trị khác nhau và rõ ràng được liên kết chặt chẽ với vị trí (hộp địa lý), nhưng nếu chỉ số tốt nhất tiếp theo để cắt giảm kích thước hàng là file_type thì tôi nên sử dụng tiếp theo. Tôi không mong đợi người dùng thường sử dụng quốc gia hoặc ngày trong bộ truy vấn của họ.
  6. Tôi KHÔNG phải lo lắng về việc tạo một chỉ mục tổng hợp gồm 4 khóa sẽ làm tăng đáng kể kích thước của dữ liệu chỉ mục. Tức là nếu một chỉ số một khóa sẽ tăng 90% hiệu suất, thì việc thêm 3 mục nữa để làm cho nó trở nên phức tạp. Ngược lại, tôi thực sự nên tạo cả hai chỉ mục. Một chỉ mục địa lý duy nhất, và cũng là một chỉ số tổng hợp, và để cho người lập kế hoạch tìm ra cái nào là tốt nhất, và nó sẽ tính đến kích thước của bảng chỉ mục.

Một lần nữa, tôi không yêu cầu bất cứ ai thiết kế giải pháp của mình, tôi không mooch về công việc của người khác. Nhưng tôi cần những thứ mà tài liệu PostGreQuery không cho tôi biết về việc triển khai

[Lý do tôi chưa có kết quả GIẢI THÍCH để hiển thị, là tôi phải tạo bảng hàng 25K này từ bảng hàng 24M. Nó đang mất nhiều thời gian hơn tôi nghĩ. Tôi đang phân cụm mọi thứ thành 1.000 nhóm mục và để người dùng truy vấn theo bảng hàng 25K. Nhưng câu hỏi tiếp theo của tôi, sẽ liên quan đến việc sử dụng kết quả của truy vấn đó để đi đến bảng hàng MASTER 25M và kéo mọi thứ ra, và đó là nơi hiệu suất của chỉ số ghép sẽ thực sự HIT].


truy vấn mẫu dưới đây:


SELECT
    public.product_list_meta_mv.cntry_name       AS country,
    public.product_list_meta_mv.product_producer AS producer,
    public.product_list_meta_mv.product_name     AS prod_name,
    public.product_list_meta_mv.product_type     AS ptype,
    public.product_list_meta_mv.product_size     AS size,
    ST_AsGeoJSON(public.product_list_meta_mv.the_geom, 10, 2)          AS outline
FROM
    public.product_list_meta_mv 
WHERE
    public.product_list_meta_mv.cntry_name = 'Poland' 
AND
    ST_Intersects(public.product_list_meta_mv.the_geom,
    st_geogfromtext('SRID=4326;POLYGON((21.23107910156250 51.41601562500000,
                                        18.64379882812500 51.41601562500000,
                                        18.64379882812500 48.69415283203130,
                                        21.23107910156250 48.69415283203130,
                                        21.23107910156250 51.41601562500000))')) 
AND (date >= '1/2/1900 5:00:00 AM' 
 AND date <= '2/26/2014 10:26:44 PM')
AND (public.product_list_meta_mv.product_type in
    ('CIB10','DTED0','DTED1','DTED2','CIB01','CIB05')) ;

GIẢI THÍCH kết quả PHÂN TÍCH (Tôi đã không đưa vào bất kỳ chỉ số tổng hợp nào và từ tốc độ tôi đang thấy tôi không biết nếu tôi cần).

"Bitmap Heap Scan on catalog_full cat  (cost=4.33..37.49 rows=1 width=7428) (actual time=1.147..38.051 rows=35 loops=1)"
"  Recheck Cond: ('0103000020E61000000100000005000000000000005838354000000000AEB0494000000000A0A7324000000000AEB0494000000000A0A73240000000006C5D48400000000058383540000000006C5D4840000000005838354000000000AEB04940'::geography && outline)"
"  Filter: (((type)::text = ANY ('{CADRG,CIB10,DTED1,DTED2}'::text[])) AND (_st_distance('0103000020E61000000100000005000000000000005838354000000000AEB0494000000000A0A7324000000000AEB0494000000000A0A73240000000006C5D48400000000058383540000000006C5D4840000000005838354000000000AEB04940'::geography, outline, 0::double precision, false) < 1e-005::double precision))"
"  Rows Removed by Filter: 61"
"  ->  Bitmap Index Scan on catalog_full_outline_idx  (cost=0.00..4.33 rows=8 width=0) (actual time=0.401..0.401 rows=96 loops=1)"
"        Index Cond: ('0103000020E61000000100000005000000000000005838354000000000AEB0494000000000A0A7324000000000AEB0494000000000A0A73240000000006C5D48400000000058383540000000006C5D4840000000005838354000000000AEB04940'::geography && outline)"
"Total runtime: 38.109 ms"

EXPLAIN ANALYZE SELECT pid,product_name,type,country,date,size,cocom,description,egpl_date,ST_AsGeoJSON(outline, 10, 2) AS outline 
FROM portal.catalog_full AS cat 
WHERE ST_Intersects(st_geogfromtext('SRID=4326;POLYGON((21.2200927734375 51.38031005859375, 18.65478515625 51.38031005859375, 18.65478515625 48.7298583984375, 21.2200927734375 48.7298583984375, 21.2200927734375 51.38031005859375))'), cat.outline) 
AND (cat.type in ('CADRG','CIB10','DTED1','DTED2'))

2
Cung cấp các truy vấn thực tế, xin vui lòng.
ypercubeᵀᴹ

Có phải "3 tùy chọn" có nghĩa là truy vấn có thể có 8 biến thể khác nhau (tùy thuộc vào việc tùy chọn 2,3,4 có được kích hoạt hay không)?
ypercubeᵀᴹ

Có 4 thành phần VÀ đến đâu. Trên st_intersects là bắt buộc, những cái khác có thể ở đó, hoặc họ có thể không. Nhưng tôi muốn giải quyết trường hợp tất cả họ đều có mặt.

2
Tôi đã bỏ phiếu để di chuyển câu hỏi sang dba.se, đây là một truy vấn phức tạp với nhiều điều kiện phạm vi.
ypercubeᵀᴹ

1
Hiển thị EXPLAIN ANALYZEcho truy vấn.
Craig Ringer

Câu trả lời:


4

Là một phần trong công việc của tôi, tôi duy trì một cơ sở dữ liệu PostgreSQL khá lớn (khoảng 120gb trên đĩa, một số bảng nhiều triệu hàng) và đã thu thập một vài thủ thuật về cách tăng tốc các truy vấn. Đầu tiên một số ý kiến ​​về các giả định của bạn:

  1. Đúng, thứ tự rất quan trọng, nhưng nó chỉ là thứ nhất thực sự khác biệt, phần còn lại là chỉ số hạng hai.
  2. Tôi không chắc chắn nó sẽ luôn sử dụng cả hai, tôi đoán là trình hoạch định truy vấn sẽ sử dụng số 1, sau đó làm điều gì đó thông minh với phần còn lại.
  3. Tôi không có kinh nghiệm với GIST.
  4. Có, thêm tất cả các chỉ mục trước, xem những gì được sử dụng nhiều nhất và những gì mang lại hiệu suất tốt nhất.
  5. Tôi sẽ nói rằng bạn thử cả hai và đo những gì hoạt động tốt nhất. Hãy thử viết lại sql với các truy vấn con khác nhau, có thể là quốc gia và thời gian trong một, sau đó tham gia với truy vấn giao nhau. Tôi không nhận thấy bất kỳ vấn đề hiệu suất nào với các mệnh đề IN, miễn là danh sách IN không dài hàng nghìn phần tử. Tôi đoán là một vài truy vấn khác nhau được điều chỉnh cụ thể tùy thuộc vào tiêu chí đầu vào có sẵn sẽ cho kết quả tốt nhất.
  6. Tôi sẽ đề nghị chống lại việc lập chỉ mục 4 chiều. Hãy thử tạo một cái và sau đó kiểm tra kích thước, chúng có thể trở nên rất lớn. Theo kinh nghiệm của tôi, bốn chỉ số 1 khóa gần như nhanh bằng một chỉ mục 4 chiều. Một mẹo hoạt động độc đáo đối với một số truy vấn cụ thể là các chỉ mục một phần, tức là một cái gì đó như thế này:

    TẠO INDEX ON bảng_x (key1, key2, key3) WHERE some_x_column = 'XXXX';

Tôi đã tạo các bí danh trong tệp .psqlrc của mình bằng các truy vấn để giúp tìm các chỉ mục cần thêm hoặc xóa. Hãy xem qua tại GitHub: .psql

Tôi sử dụng: seq_scans và: bigtables rất nhiều, sau đó \ d tên_bảng để biết chi tiết về bảng. Đừng quên đặt lại số liệu thống kê sau khi bạn thực hiện một số thay đổi, chọn pg_stat_reset ();


1
Đây là những lời khuyên tuyệt vời. Tôi đã lấy lời khuyên của bạn, và sau đó sử dụng điều này để thực hiện một thử nghiệm trên một bảng lớn hơn nhiều mà chúng tôi duy trì (43 triệu hàng). Kết quả có tại: dba.stackexchange.com/questions/61084/iêu
Dr.YSG 17/03/2016

1

Tôi nghĩ rằng điều có khả năng nhất sẽ giúp (nếu có bất cứ điều gì) sẽ là thêm sản phẩm_type làm cột thứ 2 vào chỉ mục chính. Nhưng không biết có bao nhiêu hàng khớp với từng điều kiện AND (cách ly) cho các truy vấn điển hình / có vấn đề của bạn, chúng tôi chỉ có thể đoán.

Khi tôi tiếp cận điều này, điều đầu tiên tôi làm là chạy truy vấn ở dạng đơn giản trong đó mệnh đề WHERE chỉ có một điều kiện, mỗi điều kiện được thực hiện lần lượt, trong EXPLAIN ANALYZE. Nhìn vào cả các hàng ước tính và các hàng thực tế cho từng hàng.


xem cập nhật của tôi ở trên, nhưng tôi nghĩ rằng bạn đang cho tôi một vị trí dẫn đầu tốt, hãy suy nghĩ về việc sắp xếp các chỉ mục bằng cách cắt giảm sản lượng hàng xuống nhanh nhất. Có đúng không?
Dr.YSG ngày
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.