openGauss核心分析(十):資料庫搜尋引的建立過程
資料庫索引可以提高資料的訪問速度,openGauss支援唯—索引、多欄位索引、部分索引和表示式索引。行存表(ASTORE儲存引擎)支援的索引型別:btree(行存表預設值)、hash、gin、gist。行存表(USTORE儲存引擎)支援的索引型別:ubtree。列存表支援的索引型別:Psort(列存表預設值)、btree、gin。全域性臨時表不支援GIN索引和Gist索引。
如上一篇分析資料庫表的建立過程,standard_ProcessUtility函式會根據nodeTag(parsetree)的值來確定sql的操作型別,create table一般都是進入T_CreateStmt分支呼叫CreateCommand函式。create index則進入T_IndexStmt分支呼叫DefineIndex函式。在呼叫DefineIndex前會首先執行函式transformIndexStmt,如果語句沒有指定索引型別則會使用預設值。
if (stmt->accessMethod == NULL) { if (!isColStore) { /* row store using btree index by default */ if (!RelationIsUstoreFormat(rel)) { stmt->accessMethod = DEFAULT_INDEX_TYPE; // 行存表ASTORE儲存引擎預設值btree } else { stmt->accessMethod = DEFAULT_USTORE_INDEX_TYPE; // 行存表USTORE儲存引擎預設值ubtree } …… } else { /* column store using psort index by default */ stmt->accessMethod = DEFAULT_CSTORE_INDEX_TYPE; // 列存表預設值psort } }
#define DEFAULT_INDEX_TYPE "btree"#define DEFAULT_HASH_INDEX_TYPE "hash"#define DEFAULT_CSTORE_INDEX_TYPE "psort"#define DEFAULT_GIST_INDEX_TYPE "gist"#define CSTORE_BTREE_INDEX_TYPE "cbtree"#define DEFAULT_GIN_INDEX_TYPE "gin"#define CSTORE_GINBTREE_INDEX_TYPE "cgin"#define DEFAULT_USTORE_INDEX_TYPE "ubtree"
普通表索引
DefineIndex函式
DefineIndex為建立索引主入口函式。通常建立索引以Share鎖鎖定表,允許併發查詢,但禁上對錶進行修改。如果建立索引時指定關鍵字CONCURRENTLY以不阻塞DML的方式建立索引,即允許讀取和更新表,以ShareUpdateExclusiveLock鎖鎖定表
lockmode = concurrent ? ShareUpdateExclusiveLock : ShareLock; rel = heap_open(relationId, lockmode);
如果沒有指定索引名,ChooseIndexName根據規則生成索引名
/* * Select name for index if caller didn't specify. */ indexRelationName = stmt->idxname; if (indexRelationName == NULL) { indexRelationName = ChooseIndexName(RelationGetRelationName(rel), namespaceId, indexColNames, stmt->excludeOpNames, stmt->primary, stmt->isconstraint);
為index_create函式構造引數IndexInfo結構體
/* * Prepare arguments for index_create, primarily an IndexInfo structure. * Note that ii_Predicate must be in implicit-AND format. */ indexInfo = makeNode(IndexInfo);
Index_create函式建立索引
/* * Make the catalog entries for the index, including constraints. Then, if * not skip_build || concurrent, actually build the index. */indexRelationId = index_create(rel, ……
關閉表並返回索引表id
heap_close(rel, NoLock); return indexRelationId;
Index_create函式
開啟系統表pg_class
pg_class = heap_open(RelationRelationId, RowExclusiveLock);
heap_create建立relcache和索引物理檔案
/* * create the index relation's relcache entry and physical disk file. (If * we fail further down, it's the smgr's responsibility to remove the disk * file again.) */ StorageType storage_type = RelationGetStorageType(heapRelation); indexRelation = heap_create(indexRelationName, namespaceId, tableSpaceId, indexRelationId, relFileNode, RELATION_CREATE_BUCKET(heapRelation) ? heapRelation->rd_bucketoid : InvalidOid, indexTupDesc, relKind, relpersistence, isLocalPart, false, shared_relation, mapped_relation, allow_system_table_mods, REL_CMPRS_NOT_SUPPORT, (Datum)reloptions, heapRelation->rd_rel->relowner, skip_create_storage, isUstore ? TAM_USTORE : TAM_HEAP, /* XXX: Index tables are by default HEAP Table Type */ relindexsplit, storage_type, extra->crossBucket, accessMethodObjectId);
將索引表元資訊存入系統表pg_class
/* * store index's pg_class entry */ InsertPgClassTuple( pg_class, indexRelation, RelationGetRelid(indexRelation), (Datum)0, reloptions, relKind, NULL); /* done with pg_class */ heap_close(pg_class, RowExclusiveLock);
將索引表元資訊存入系統表pg_index
UpdateIndexRelation(indexRelationId, heapRelationId, indexInfo, ……
Index_build建立索引
} else if (extra && (!extra->isPartitionedIndex || extra->isGlobalPartitionedIndex)) { /* support regular index or GLOBAL partition index */ index_build(heapRelation, NULL, indexRelation, NULL, indexInfo, isprimary, false, PARTITION_TYPE(extra)); }
index_build
index_build呼叫index_build_storage,如果建立的是btree索引最終呼叫btbuild,如果是hash索引最終呼叫hashbuild,如果是psort則最終呼叫psortbuild,更多索引訪問方法的資訊可檢視系統表pg_am。
stats = index_build_storage(targetHeapRelation, targetIndexRelation, indexInfo);
static IndexBuildResult* index_build_storage(Relation heapRelation, Relation indexRelation, IndexInfo* indexInfo) { RegProcedure procedure = indexRelation->rd_am->ambuild; Assert(RegProcedureIsValid(procedure)); IndexBuildResult* stats = (IndexBuildResult*)DatumGetPointer(OidFunctionCall3( procedure, PointerGetDatum(heapRelation), PointerGetDatum(indexRelation), PointerGetDatum(indexInfo))); Assert(PointerIsValid(stats)); if (RELPERSISTENCE_UNLOGGED == heapRelation->rd_rel->relpersistence) { index_build_init_fork(heapRelation, indexRelation); } return stats; }
btree索引的procedure為btbuild。
#0 btbuild (fcinfo=0x7fb4f9c63920) at nbtree.cpp:63#1 0x00000000011fc07d in OidFunctionCall3Coll (functionId=338, collation=0, arg1=140415366247440, arg2=140415366237480, arg3=140415402419864) at fmgr.cpp:1857#2 0x0000000000c16b77 in index_build_storage (heapRelation=0x7fb50006b410, indexRelation=0x7fb500068d28, indexInfo=0x7fb5022ea698) at index.cpp:2475#3 0x0000000000c18097 in index_build (heapRelation=0x7fb50006b410, heapPartition=0x0, indexRelation=0x7fb500068d28, indexPartition=0x0, indexInfo=0x7fb5022ea698, isPrimary=false, isreindex=false, partitionType=INDEX_CREATE_NONE_PARTITION, parallel=true) at index.cpp:2834
以上函式呼叫棧如下
#0 index_build_storage #1 index_build#2 index_create#3 DefineIndex#4 standard_ProcessUtility #5 gsaudit_ProcessUtility_hook#6 pgaudit_ProcessUtility #7 hypo_utility_hook #8 ProcessUtility #9 PortalRunUtility#10 PortalRun #11 exec_simple_query #12 PostgresMain
分割槽表索引
建立普通表索引語法如下
CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [schema_name.]index_name ] { ON table_name [ USING method ] | [ USING method ] ON table_name } ({ { column_name | ( expression ) } [ COLLATE collation ] [ opclass ] [ ASC | DESC ] [ NULLS { FIRST | LAST } ] }[, ...] ) [ index_option ] [ WHERE predicate ];
建立分割槽表索引語法
CREATE [ UNIQUE ] INDEX [ [schema_name.]index_name ] { ON table_name [ USING method ] | [ USING method ] ON table_name } ( {{ column_name | ( expression ) } [ COLLATE collation ] [ opclass ] [ ASC | DESC ] [ NULLS LAST ] }[, ...] ) [ LOCAL [ ( { PARTITION index_partition_name [ TABLESPACE index_partition_tablespace ] } [, ...] ) ] | GLOBAL ] [ index_option ]
兩者執行流程基本一致,分割槽表索引在DefineIndex中是遍歷每個分割槽呼叫partition_index_create。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70023856/viewspace-2939954/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- openGauss核心分析(九):資料庫表的建立過程資料庫
- openGauss核心:SQL解析過程分析SQL
- standby 資料庫的建立過程資料庫
- Oracle XE的資料庫建立過程Oracle資料庫
- 手工建立oracle資料庫的過程Oracle資料庫
- 手動建立資料庫過程資料庫
- Linux核心建立一個程式的過程分析Linux
- Standby資料庫簡單建立過程資料庫
- 過濾搜尋引擎的抓取資料
- openGauss資料庫分析問題資料庫
- 【elasticsearch】搜尋過程詳解Elasticsearch
- tiktok商品搜尋資料分析
- SAP CRM產品主資料搜尋功能的With individual object搜尋引數Object
- 海量資料搜尋---搜尋引擎
- 走了一遍手動建立資料庫的過程資料庫
- 使用AnalyticDB MySQL建立資料庫及表過程MySql資料庫
- 【Elasticsearch學習】文件搜尋全過程Elasticsearch
- Lucene原始碼解析--搜尋過程<二>原始碼
- 一次使用duplicate建立測試資料庫的過程資料庫
- 資料需求分析過程
- 一次資料庫硬解析的分析全過程資料庫
- 建立資料庫連線失敗ORA-12514的分析解決過程資料庫
- 極限科技榮耀入選《中國資料庫產業圖譜(2024年)》,引領搜尋與分析型資料庫新篇章資料庫產業
- 資料庫的連線過程資料庫
- 詳細說明搜尋引擎優化的過程優化
- ORACLE 資料庫分析,重新編譯失敗過程Oracle資料庫編譯
- 【資料庫】資料庫儲存過程(一)資料庫儲存過程
- Windows啟動過程(MBR引導過程分析)Windows
- 大資料分析過程是如何的大資料
- linux下Postgresql-9.2安裝及資料庫的建立過程LinuxSQL資料庫
- 使用PHP與SQL搭建可搜尋的加密資料庫PHPSQL加密資料庫
- VB6基本資料庫應用(八):模糊搜尋與基於範圍的搜尋資料庫
- 資料庫恢復過程資料庫
- 資料庫啟動過程資料庫
- 資料庫儲存過程資料庫儲存過程
- 搜尋學習基礎--倒排索引的過程解讀索引
- layui資料表格搜尋UI
- oracle資料庫的關閉過程Oracle資料庫