ฉันมีตารางที่มี 50K แถว จริงๆแล้วมันเป็นตาราง PostGIS
แบบสอบถามมี 4 ส่วน (บังคับ 1 ข้อ) (3 ตัวเลือก)
- กล่องแยก (สี่เหลี่ยมทางภูมิศาสตร์) ที่มีละติจูด 4 เส้น, ยาว (ฉันใช้ st_intersects) [จำเป็น]
- ช่วงวันที่ (นาทีสูงสุด) ในฟิลด์วันที่
- ประเภทไฟล์ (ชุดของค่าข้อความสูงสุด 8 ค่า) กำลังใช้ IN (..... ) แต่ฉันสามารถสร้างตารางชั่วคราวได้ถ้าต้องการ ฉันเห็นคนจำนวนมากไม่ชอบอิน
- ประเทศ (ค่าข้อความ)
ฉันคาดหวังประมาณ 100 - 4,000 แถวที่ส่งคืน
ถ้าฉันสร้างดัชนีผสมบนตารางฉันควรใช้คอลัมน์ใดก่อน เม็ดเล็กละเอียดน่าจะเป็นที่ตั้ง (มีการกระจายข้อมูลไปทั่วโลก) ปัจจุบันฉันมีมันเป็นดัชนีส่วนสำคัญ
ดัชนีอื่น ๆ จะเป็น BTREE
สัญชาตญาณของฉันบอกว่าใช้เนื้อละเอียดและแน่นอนที่สุด เช่นมีไฟล์ประมาณ 12 ชนิดเท่านั้นดังนั้นจึงเป็นที่เก็บข้อมูลที่ใหญ่มากสำหรับดัชนี
ผู้เชี่ยวชาญด้าน PostgreSQL และ PostGIS ทำอะไร (ใครรู้เรื่องภายในของระบบ) พูด?
UPDATE:
ให้ฉันเพิ่มพูนคำถามนี้
- ฉันไม่ต้องการให้ใครทำงานที่ฉันควรทำ ฉันเคารพเวลาของคุณมากเกินไป ดังนั้นฉันจะอธิบายการวิเคราะห์ในภายหลัง
- ทั้งหมดที่ฉันกำลังมองหาคือตัวชี้และเคล็ดลับและแนวทาง
- ฉันอ่านโพสต์เล็ก ๆ น้อย ๆ ที่ยอดเยี่ยมนี้: https://devcenter.heroku.com/articles/postgresql-indexes#managing-and-maintaining-indexesเกี่ยวกับดัชนี
- สิ่งที่ฉันทำตามปกติคือสร้างดัชนีแยกต่างหาก 4 ตัว (ภูมิศาสตร์กล่องชื่อประเทศ file_type และวันที่) แต่สิ่งที่ต้องการดูว่าแบบสอบถามแบบผสมจะทำอะไร
บอกฉันหากข้อสันนิษฐานเหล่านี้ผิด (ฉันค่อนข้างใหม่กับความคิดของดัชนีผสม)
- คำสั่งซื้อเป็นสิ่งสำคัญ เลือกเป็นดัชนีแรกซึ่งจะตัดแถวลงมากที่สุด (ในกรณีของฉันตำแหน่ง (ภูมิศาสตร์) ซึ่งเป็นรูปหลายเหลี่ยมแบบง่ายหรือหลายรูปหลายเหลี่ยมจะทำได้ดีที่สุด)
- บางครั้งการสืบค้นจะข้ามดัชนี แต่ถ้าฉันสร้างแบบสอบถามแบบผสมพร้อมคีย์ (# 1, # 2, # 3, # 4) แม้ว่าผู้ใช้จะสร้างสิ่งที่ถาม # 1, # 3 ผู้วางแผนจะยังคงใช้แบบสอบถามแบบประกอบเดียวเนื่องจากพวกเขาสั่ง ถูกเก็บรักษาไว้
- โดยปกติฉันจะสร้างแบบสอบถาม BTREE สามรายการและรายการหนึ่งรายการ (สำหรับประเภทภูมิศาสตร์) PostGIS ไม่สนับสนุนการสร้างสารประกอบหลายประเภทดัชนี ดังนั้นฉันจะต้องใช้ GIST ดัชนีผสม แต่นั่นไม่ควรทำร้ายสิ่งต่าง ๆ
- ถ้าฉันจะสร้างสารประกอบเพิ่มเติมหรือดัชนีค่าเดียวนักวางแผนนั้นฉลาดพอที่จะเลือกอันที่ฉลาดที่สุด .....
- ชื่อประเทศสามารถมีค่าได้ประมาณ 250 ค่าและเห็นได้ชัดว่ามีการเชื่อมโยงอย่างแน่นหนากับตำแหน่ง (geobox) แต่ถ้าดัชนีที่ดีที่สุดถัดไปสำหรับการลดขนาดแถวคือ file_type ฉันควรใช้ต่อไป ฉันไม่คาดหวังให้ผู้ใช้มักใช้ประเทศหรือวันที่ในชุดแบบสอบถาม
- ฉันไม่ต้องกังวลเกี่ยวกับการสร้างดัชนีรวม 4 ปุ่มจะเพิ่มขนาดของข้อมูลดัชนีอย่างมาก คือถ้าดัชนีคีย์เดียวจะเป็น 90% ของการเพิ่มประสิทธิภาพจะไม่เจ็บที่จะเพิ่ม 3 รายการเพิ่มเติมเพื่อให้รวมกัน ในทางกลับกันฉันควรสร้างดัชนีทั้งคู่ ดัชนีภูมิศาสตร์เดียวและดัชนีผสมและให้นักวางแผนเข้าใจว่าสิ่งใดดีที่สุดและจะคำนึงถึงขนาดของตารางดัชนี
อีกครั้งฉันไม่ได้ขอให้ทุกคนออกแบบวิธีแก้ปัญหาของฉันฉันไม่ดื่มเหล้าจากการทำงานของคนอื่น แต่ฉันต้องการสิ่งที่เอกสาร PostGreSQL ไม่ได้บอกฉันเกี่ยวกับการใช้งาน
[เหตุผลที่ฉันยังไม่มีผลลัพธ์อธิบายให้แสดงก็คือฉันต้องสร้างตารางแถว 25K นี้จากตารางแถว 24M ใช้เวลามากกว่าที่ฉันคิด ฉันกำลังรวมกลุ่มสิ่งต่าง ๆ เป็น 1,000 กลุ่มรายการและให้ผู้ใช้คิวรีกับตารางแถว 25K แต่คำถามต่อไปของฉันจะเกี่ยวข้องกับการใช้ผลลัพธ์ของแบบสอบถามนั้นเพื่อไปที่ตารางแถว MASTER 25M แล้วดึงสิ่งต่าง ๆ ออกมาและนั่นเป็นจุดที่ประสิทธิภาพของดัชนีผสมจะเป็นจริง]
แบบสอบถามตัวอย่างด้านล่าง:
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')) ;
อธิบายผลการวิเคราะห์ (ฉันไม่ได้ใส่ดัชนีผสมใด ๆ และจากความเร็วที่ฉันเห็นฉันไม่รู้ว่าต้องการหรือไม่)
"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
สำหรับแบบสอบถาม