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)
- 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]
- Phạm vi ngày (tối thiểu, tối đa) trên trường ngày
- 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.
- 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.
- 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.
- 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.
- 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
- 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)
- 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).
- Đô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ì.
- 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ứ.
- 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 .....
- 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ọ.
- 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'))
EXPLAIN ANALYZE
cho truy vấn.