如果要檢查某些索引是否有助于一個或多個查詢,則 HypoPG 非常有用。因此,您應該已經(jīng)知道需要優(yōu)化哪些查詢,以及要嘗試哪些索引。
此外,HypoPG 將要創(chuàng)建的假設索引不會存儲在任何系統(tǒng)表中,而是存儲在您連接的私有內(nèi)存中。因此,它不會使任何表出現(xiàn)膨脹,也不會影響任何并發(fā)連接。
此外,由于假設索引實際上并不存在,因此 HypoPG 僅能確保在使用簡單的 EXPLAIN 語句(不帶 ANALYZE 選項)時會使用它們。
跟任何其他擴展一樣,您必須將其安裝在希望能夠使用它的所有數(shù)據(jù)庫上。只需用一個有足夠權限的用戶,連接到要安裝 HypoPG 的數(shù)據(jù)庫上,執(zhí)行以下查詢即可完成:
CREATE EXTENSION hypopg;
現(xiàn)在就可以使用 HypoPG 了。您可以使用 psql 輕松地檢查擴展是否存在:
/dx List of installed extensions Name | Version | Schema | Description---------+---------+------------+------------------------------------- hypopg | 1.1.0 | public | Hypothetical indexes for PostgreSQL plpgsql | 1.0 | pg_catalog | PL/pgSQL procedural language(2 rows)
如您所見,已安裝了 hypopg 版本 1.1.0。如果需要使用純 SQL 進行檢查,請參考 pg_extension 表文檔。
以下是可用的配置參數(shù)(GUC),并且可以交互式更改:
? hypopg.enabled:默認為on。使用此參數(shù)可全局啟用或禁用 HypoPG。禁用 HypoPG 后,任何假設索引都不會被使用,但不會刪除定義的假設索引。
? hypopg.use_real_oids:默認為off。默認情況下,HypoPG 不會使用 “真實的” 對象標識符,而是從 ~ 14000 / 16384(分別是低于 FirstNormalObjectId 的最低未使用的 oid 和 FirstNormalObjectId)范圍內(nèi)借用標識符,這些標識符由 PostgreSQL 保留,以備將來在未來的版本中使用。這不會造成任何問題,因為可用范圍是在連接首次使用 HypoPG 時動態(tài)計算的,并且還有可以應用在備用服務器上的優(yōu)勢。但缺點是,您不能同時擁有大約 2500 個假設索引,并且一旦已經(jīng)創(chuàng)建了超出最多數(shù)目的對象,創(chuàng)建新的假設索引會變得非常慢,一直到hypopg_reset()被調(diào)用。如果這些缺點有問題,您可以啟用此參數(shù)。然后,HypoPG 將要求提供真實的對象標識符,這將需要獲取更多鎖,并且不會在備用服務器工作,但允許使用所有可用的對象標識符。請注意,切換此參數(shù)不需要重置已經(jīng)定義的假設索引,兩者可以同時共存。
支持以下訪問方式:
? btree
? brin
? hash(需要 PostgreSQL 10 或更高版本)
? bloom(需要安裝 bloom 擴展)
注意:使用 HypoPG 需要對 EXPLAIN 命令有一定的了解。如果您需要有關此命令的更多信息,可以查看官方文檔。另外也還有很多非常好的資源。
為了清楚起見,讓我們使用一個非常簡單的測試用例,看看它是如何工作的:
CREATE TABLE hypo (id integer, val text);INSERT INTO hypo SELECT i, 'line ' || i FROM generate_series(1, 100000) i;VACUUM ANALYZE hypo;
此表沒有任何索引。假設我們要檢查索引是否有助于簡單的查詢。首先,讓我們看看它的表現(xiàn):
EXPLAIN SELECT val FROM hypo WHERE id = 1; QUERY PLAN-------------------------------------------------------- Seq Scan on hypo (cost=0.00..1791.00 rows=1 width=14) Filter: (id = 1)(2 rows)
由于表上不存在索引,因此使用了普通的順序掃描。在 id 列上創(chuàng)建一個簡單 btree 索引,應該有助于此查詢。讓我們來看看 HypoPG。函數(shù) hypopg_create_index() 可接受任何標準的 CREATE INDEX 語句(傳遞給此函數(shù)的任何其他語句都會被忽略),并為每個語句創(chuàng)建一個假設索引:
SELECT * FROM hypopg_create_index('CREATE INDEX ON hypo (id)'); indexrelid | indexname------------+---------------------- 18284 | <18284>btree_hypo_id(1 row)
該函數(shù)返回兩列:
? 假設索引的對象標識符
? 生成的假設索引名稱
我們可以再次運行 EXPLAIN,來查看 PostgreSQL 是否會使用這個索引:
EXPLAIN SELECT val FROM hypo WHERE id = 1; QUERY PLAN---------------------------------------------------------------------------------- Index Scan using <18284>btree_hypo_id on hypo (cost=0.04..8.06 rows=1 width=10) Index Cond: (id = 1)(2 rows)
是的,PostgreSQL 會使用這樣的索引。為了確定,讓我們檢查下實際運行查詢的時候,假設索引不會被用到:
EXPLAIN ANALYZE SELECT val FROM hypo WHERE id = 1; QUERY PLAN--------------------------------------------------------------------------------------------------- Seq Scan on hypo (cost=0.00..1791.00 rows=1 width=10) (actual time=0.046..46.390 rows=1 loops=1) Filter: (id = 1) Rows Removed by Filter: 99999 Planning time: 0.160 ms Execution time: 46.460 ms(5 rows)
這就是創(chuàng)建假設索引并查看 PostgreSQL 是否會使用此類索引的全部內(nèi)容。
還有一些其他的很方便的函數(shù)和視圖:
? hypopg_list_indexes:列出已創(chuàng)建的所有假設索引的視圖
SELECT * FROM hypopg_list_indexes; indexrelid | index_name | schema_name | table_name | am_name------------+-----------------------+-------------+------------+--------- 18284 | <18284>btree_hypo_id | public | hypo | btree(1 row)
? **hypopg()**:采用和 pg_index 相同的格式,列出所有已創(chuàng)建的假設索引的函數(shù)
SELECT * FROM hypopg(); indexname | indexrelid | indrelid | innatts | indisunique | indkey | indcollation | indclass | indoption | indexprs | indpred | amid----------------------+------------+----------+---------+-------------+--------+--------------+----------+-----------+----------+---------+------ <18284>btree_hypo_id | 13543 | 18122 | 1 | f | 1 | 0 | 1978 | <NULL> | <NULL> | <NULL> | 403(1 row)
? **hypopg_get_indexdef(oid)**:列出 CREATE INDEX 語句的函數(shù),該語句可用于重新創(chuàng)建存儲的假設索引
SELECT index_name, hypopg_get_indexdef(indexrelid) FROM hypopg_list_indexes; index_name | hypopg_get_indexdef-----------------------+---------------------------------------------- <18284>btree_hypo_id | CREATE INDEX ON public.hypo USING btree (id)(1 row)
? **hypopg_relation_size(oid)**:用于估計一個假設索引的大小的函數(shù):
SELECT index_name, pg_size_pretty(hypopg_relation_size(indexrelid)) FROM hypopg_list_indexes; index_name | pg_size_pretty-----------------------+---------------- <18284>btree_hypo_id | 2544 kB(1 row)
? **hypopg_drop_index(oid)**:用于刪除指定假設索引的函數(shù)
? **hypopg_reset()**:用于刪除所有假設索引的函數(shù)
您可以假設性隱藏現(xiàn)有索引和假設索引。如果要按照文檔中的說明對其進行測試,則應首先使用 hypopg_reset() 清除任何其他假設索引的影響。
舉個簡單的例子,讓我們考慮兩個索引:
SELECT hypopg_reset();CREATE INDEX ON hypo(id);CREATE INDEX ON hypo(id, val);
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)
查詢計劃現(xiàn)在正使用 hypo_id_val_idx 索引。
? **hypopg_hide_index(oid)**:允許您使用 EXPLAIN 輸出中的索引 OID 來隱藏索引的函數(shù)。如果索引已成功隱藏,則返回 true,否則返回 false。
SELECT hypopg_hide_index('hypo_id_val_idx'::REGCLASS); hypopg_hide_index------------------- t(1 row)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_val_idx 索引。若要繼續(xù)測試,請使用 hypopg_hide_index(oid) 函數(shù)隱藏另一個索引。
SELECT hypopg_hide_index('hypo_id_idx'::REGCLASS); hypopg_hide_index------------------- t(1 row)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_unhide_index(oid)**:使用其 OID 還原 EXPLAIN 輸出中以前隱藏的索引的函數(shù)。如果索引已成功還原,則返回 true,否則返回 false。
SELECT hypopg_unhide_index('hypo_id_idx'::regclass); hypopg_unhide_index------------------- t(1 row)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)
? **hypopg_unhide_all_index()**:恢復所有隱藏的索引,并返回 void 的函數(shù)。
? **hypopg_hidden_indexes()**:返回所有隱藏的索引的 OID 列表的函數(shù)。
SELECT * FROM hypopg_hidden_indexes(); indexid--------- 526604(1 rows)
? hypopg_hidden_indexes:返回所有隱藏的索引的格式化列表的視圖。
SELECT * FROM hypopg_hidden_indexes; indexrelid | index_name | schema_name | table_name | am_name | is_hypo-------------+----------------------+-------------+------------+---------+--------- 526604 | hypo_id_val_idx | public | hypo | btree | f(1 rows)
注意:假設索引也是可以隱藏的。
SELECT hypopg_create_index('CREATE INDEX ON hypo(id)'); hypopg_create_index------------------------------ (12659,<12659>btree_hypo_id)(1 row)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)
現(xiàn)在該假設索引正在被使用,我們可以嘗試隱藏它,以查看更改:
SELECT hypopg_hide_index(12659); hypopg_hide_index------------------- t(1 row)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)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 526604 | hypo_id_val_idx | public | hypo | btree | f(2 rows)
注意:如果假設索引已被隱藏,則在使用 hypopg_drop_index(oid) 或 hypopg_reset() 刪除該索引時,它將自動取消隱藏。
SELECT hypopg_drop_index(12659);SELECT * FROM hypopg_hidden_indexes; indexrelid | index_name | schema_name | table_name | am_name | is_hypo-------------+----------------------+-------------+------------+---------+--------- 526604 | hypo_id_val_idx | public | hypo | btree | f(2 rows)
本文鏈接:http://www.www897cc.com/showinfo-26-79978-0.html要驗證索引是否有效,不一定要馬上創(chuàng)建索引哦
聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。郵件:2376512515@qq.com