HypOPG เป็นส่วนขยายการเพิ่มส่วนขยาย PostgreSQL สำหรับดัชนีสมมุติฐาน
ดัชนีสมมุติฐาน - หรือเสมือน - เป็นดัชนีที่ไม่มีอยู่จริงและไม่ต้องเสียค่าใช้จ่าย CPU, ดิสก์หรือทรัพยากรใด ๆ ที่จะสร้าง พวกเขามีประโยชน์ที่จะทราบว่าดัชนีเฉพาะสามารถเพิ่มประสิทธิภาพสำหรับการสืบค้นที่มีปัญหาหรือไม่เนื่องจากคุณสามารถทราบได้ว่า PostgreSQL จะใช้ดัชนีเหล่านี้หรือไม่โดยไม่ต้องใช้ทรัพยากรเพื่อสร้าง
สำหรับข้อมูลที่ละเอียดยิ่งขึ้นโปรดปรึกษาเอกสารอย่างเป็นทางการ
สำหรับข้อมูลทั่วไปอื่น ๆ คุณสามารถปรึกษาโพสต์บล็อกนี้ได้
sudo make installCREATE EXTENSION hypopg; โปรดทราบว่า HypOPG ไม่ได้ให้สคริปต์การอัพเกรดส่วนขยายเนื่องจากไม่มีข้อมูลที่บันทึกไว้ในวัตถุใด ๆ ที่สร้างขึ้น ดังนั้นคุณต้องวางส่วนขยายก่อนจากนั้นสร้างอีกครั้งเพื่อรับเวอร์ชันใหม่
หมายเหตุ: ดัชนีสมมุติฐานมีอยู่ในแบ็กเอนด์เดียว ดังนั้นหากคุณเพิ่มดัชนีสมมุติฐานหลายรายการการเชื่อมต่อที่เกิดขึ้นพร้อมกันในการ EXPLAIN จะไม่ถูกรบกวนจากดัชนีสมมุติฐานของคุณ
สมมติว่ากรณีทดสอบง่าย ๆ :
rjuju=# CREATE TABLE hypo AS SELECT id, 'line ' || id AS val FROM generate_series(1,10000) id;
rjuju=# EXPLAIN SELECT * FROM hypo WHERE id = 1;
QUERY PLAN
-------------------------------------------------------
Seq Scan on hypo (cost=0.00..180.00 rows=1 width=13)
Filter: (id = 1)
(2 rows)
วิธีที่ง่ายที่สุดในการสร้างดัชนีสมมุติฐานคือการใช้ฟังก์ชั่น hypopg_create_index ด้วยคำสั่ง CREATE INDEX ปกติเป็น arg
ตัวอย่างเช่น:
rjuju=# SELECT * FROM hypopg_create_index('CREATE INDEX ON hypo (id)');
หมายเหตุ: ข้อมูลบางอย่างจากคำสั่ง CREATE INDEX จะถูกละเว้นเช่นชื่อดัชนีหากมีให้ ข้อมูลบางส่วนที่ถูกเพิกเฉยจะได้รับการจัดการในการเปิดตัวในอนาคต
คุณสามารถตรวจสอบดัชนีสมมุติฐานที่มีอยู่ในแบ็กเอนด์ของคุณเอง:
rjuju=# SELECT * FROM hypopg_list_indexes ;
indexrelid | index_name | schema_name | table_name | am_name
------------+-------------------------------+-------------+------------+---------
50573 | <50573>btree_hypo_id | public | hypo | btree
หากคำสั่ง CREATE INDEX ที่คุณต้องการใช้ยังต้องใช้การอ้างถึงการใช้ไวยากรณ์การอ้างอิงดอลลาร์จะแนะนำ ตัวอย่างเช่น:
rjuju=# SELECT * FROM hypopg_create_index($$CREATE INDEX ON hypo (id) WHERE val = 'line 1'$$);
หากคุณต้องการข้อมูลทางเทคนิคเพิ่มเติมเกี่ยวกับดัชนีสมมุติฐานฟังก์ชั่น hypopg() จะส่งคืนดัชนีสมมุติฐานในลักษณะเดียวกันกับแคตตาล็อกระบบ pg_index
และตอนนี้มาดูกันว่าคำสั่ง EXPLAIN ก่อนหน้าของคุณจะใช้ดัชนีดังกล่าวหรือไม่:
rjuju=# EXPLAIN SELECT * FROM hypo WHERE id = 1;
QUERY PLAN
------------------------------------------------------------------------------------
Index Scan using <41072>hypo_btree_hypo_id on hypo (cost=0.29..8.30 rows=1 width=13)
Index Cond: (id = 1)
(2 rows)
แน่นอน EXPLAIN โดยไม่มี ANALYZE เท่านั้นที่จะใช้ดัชนีสมมุติฐาน:
rjuju=# EXPLAIN ANALYZE SELECT * FROM hypo WHERE id = 1;
QUERY PLAN
-------------------------------------------------------------------------------------------------
Seq Scan on hypo (cost=0.00..180.00 rows=1 width=13) (actual time=0.036..6.072 rows=1 loops=1)
Filter: (id = 1)
Rows Removed by Filter: 9999
Planning time: 0.109 ms
Execution time: 6.113 ms
(5 rows)
ในการลบดัชนีสมมุติฐานของแบ็กเอนด์ของคุณคุณสามารถใช้ฟังก์ชัน hypopg_drop_index(indexrelid) กับ OID ที่มุมมอง hypopg_list_indexes กลับมาและโทร hypopg_reset() เพื่อลบทั้งหมดในครั้งเดียวหรือเพียงแค่ปิดการเชื่อมต่อปัจจุบันของคุณ
ดำเนินการต่อด้วยกรณีข้างต้นคุณสามารถ hide existing indexes แต่ควรใช้ hypopg_reset() เพื่อล้างผลกระทบก่อนหน้าของดัชนีอื่น ๆ ในตอนแรก
สร้างดัชนีจริงสองตัวและเรียกใช้ EXPLAIN :
rjuju=# SELECT hypopg_reset();
rjuju=# CREATE INDEX ON hypo(id);
rjuju=# CREATE INDEX ON hypo(id, val);
rjuju=# EXPLAIN SELECT * FROM hypo WHERE id = 1;
QUERY PLAN
----------------------------------------------------------------------------------
Index Only Scan using hypo_id_val_idx on hypo (cost=0.29..8.30 rows=1 width=13)
Index Cond: (id = 1)
(2 rows)
แผนค้นหากำลังใช้ดัชนี hypo_id_val_idx ใช้ hypopg_hide_index(oid) เพื่อซ่อนหนึ่งในดัชนี:
rjuju=# SELECT hypopg_hide_index('hypo_id_val_idx'::REGCLASS);
rjuju=# EXPLAIN SELECT * FROM hypo WHERE id = 1;
QUERY PLAN
-------------------------------------------------------------------------
Index Scan using hypo_id_idx on hypo (cost=0.29..8.30 rows=1 width=13)
Index Cond: (id = 1)
(2 rows)
แผนค้นหากำลังใช้ดัชนีอื่น ๆ hypo_id_idx ในขณะนี้ ใช้ hypopg_hide_index(oid) เพื่อซ่อน:
rjuju=# SELECT hypopg_hide_index('hypo_id_idx'::REGCLASS);
rjuju=# EXPLAIN SELECT * FROM hypo WHERE id = 1;
QUERY PLAN
-------------------------------------------------------
Seq Scan on hypo (cost=0.00..180.00 rows=1 width=13)
Filter: (id = 1)
(2 rows)
และตอนนี้แผนคิวรีเปลี่ยนกลับเป็น Seq Scan ใช้ hypopg_unhide_index(oid) เพื่อกู้คืนดัชนี:
rjuju=# SELECT hypopg_unhide_index('hypo_id_idx'::regclass);
rjuju=# EXPLAIN SELECT * FROM hypo WHERE id = 1;
QUERY PLAN
-------------------------------------------------------------------------
Index Scan using hypo_id_idx on hypo (cost=0.29..8.30 rows=1 width=13)
Index Cond: (id = 1)
(2 rows)
แน่นอนคุณสามารถซ่อนดัชนีสมมุติฐาน:
rjuju=# SELECT hypopg_create_index('CREATE INDEX ON hypo(id)');
rjuju=# EXPLAIN SELECT * FROM hypo WHERE id = 1;
QUERY PLAN
------------------------------------------------------------------------------------
Index Scan using "<12659>btree_hypo_id" on hypo (cost=0.04..8.05 rows=1 width=13)
Index Cond: (id = 1)
(2 rows)
rjuju=# SELECT hypopg_hide_index(12659);
rjuju=# EXPLAIN SELECT * FROM hypo WHERE id = 1;
QUERY PLAN
-------------------------------------------------------
Seq Scan on hypo (cost=0.00..180.00 rows=1 width=13)
Filter: (id = 1)
(2 rows)
คุณสามารถตรวจสอบว่าดัชนีใดที่ซ่อนอยู่โดยใช้ hypopg_hidden_indexes() หรือมุมมอง hypopg_hidden_indexes :
rjuju=# SELECT * FROM hypopg_hidden_indexes();
indexid
---------
526604
526603
12659
(3 rows)
rjuju=# SELECT * FROM hypopg_hidden_indexes;
indexrelid | index_name | schema_name | table_name | am_name | is_hypo
------------+----------------------+-------------+------------+---------+---------
12659 | <12659>btree_hypo_id | public | hypo | btree | t
526603 | hypo_id_idx | public | hypo | btree | f
526604 | hypo_id_val_idx | public | hypo | btree | f
(3 rows)
ในการกู้คืนดัชนีที่มีอยู่ทั้งหมดคุณสามารถใช้ฟังก์ชั่น hypopg_unhide_all_indexes() โปรดทราบว่าฟังก์ชันการทำงานเพื่อซ่อนดัชนีที่มีอยู่จะใช้เฉพาะกับคำสั่งอธิบายในเซสชันปัจจุบันและจะไม่ส่งผลกระทบต่อเซสชันอื่น ๆ