日本熟妇hd丰满老熟妇,中文字幕一区二区三区在线不卡 ,亚洲成片在线观看,免费女同在线一区二区

優化查詢性能

本文為您介紹在Hologres中對內部表性能進行調優的最佳實踐。

更新統計信息

統計信息決定是否能夠生成正確的執行計劃。例如,Hologres需要收集數據的采樣統計信息,包括數據的分布和特征、表的統計信息、列的統計信息、行數、列數、字段寬度、基數、頻度、最大值、最小值、長鍵值、分桶分布特征等信息。這些信息將為優化器更新算子執行預估COST、搜索空間裁剪、估算最優Join Order、估算內存開銷、估算并行度,從而生成更優的執行計劃。關于統計信息更多的介紹,請參見Using Explain

統計信息的收集也存在一定局限,主要是針對非實時、手動觸發或者周期性觸發,不一定反映最準確的數據特征。您需要先檢查explain的信息,查看explain中包含的統計信息是否正確。統計信息中每個算子的rowswidth表示該算子的行數和寬度。

查看統計信息是否正確

通過查看執行計劃:

未及時同步統計信息導致生成較差的執行計劃,示例如下:

tmp1表的數據量為1000萬行,tmp表的數據量為1000行。 Hologres默認統計信息中的行數為1000行,通過執行explainSQL語句,如下展示結果所示,tmp1表的行數與實際的行數不符,該展示結果表明未及時更新統計信息。

Seq Scan on tmp1 (cost=0.00..5.01 rows=1000 width=1)

示例

更新統計信息

tmp1tmp表Join時,正確的explain信息展示為數據量大的表tmp1在數據量小的表tmp上方,Hash Join應該采用數據量小的tmp表。因為tmp1表未及時更新統計信息,導致Hologres選擇tmp1表創建Hash表進行Hash Join,效率較低,并且可能造成OOM(Out Of Memory,內存溢出)。因此,需要參與Join的兩張表均執行analyze收集統計信息,語句如下。

analyze tmp;
analyze tmp1;

執行analyze命令后,Join的順序正確。數據量大的表tmp1在數據量小的表tmp上方,使用數據量小的表tmp做Hash表,如下圖所示。并且tmp1表展示的行數為1000萬行,表明統計信息已經更新。順序

當發現explain返回結果中rows=1000,說明缺少統計信息。一般性能不好時,其原因通常是優化器缺少統計信息,需要通過及時更新統計信息,執行analyze <tablename>,可以簡單快捷優化查詢性能。

推薦更新統計信息的場景

推薦在以下情況下運行analyze <tablename>命令。

  • 導入數據之后。

  • 大量的INSERT、UPDATE以及DELETE操作之后。

  • 內部表、外部表均需要ANALYZE。

  • 分區表針對父表做ANALYZE。

  • 如果遇到以下問題,您需要先執行analyze <tablename>,再運行導入任務,可以系統地優化效率。

    • 多表JOIN超出內存OOM。

      通常會產生Query executor exceeded total memory limitation xxxxx: yyyy bytes used報錯。

    • 導入效率較低。

      在Hologres查詢或導入數據時,效率較低,運行的任務長時間不結束。

設置適合的Shard數

Shard數代表查詢執行的并行度。Shard個數對查詢性能影響至關重要,Shard數設置少,會導致并行度不足。Shard數設置過多,也會引起查詢啟動開銷大,降低查詢效率,同時引起小文件過多,占用內存更多的元數據管理空間。設置與實例規格匹配的Shard數,可以改善查詢效率,降低內存開銷。

Hologres為每個實例設置了默認的Shard數,Shard數約等于實例中用于核心查詢的Core數。這里的core數,略小于實際購買的Core數(實際購買的Core會被分配給不同的節點,包括查詢節點、接入節點、控制節點和調度節點等)。不同規格實例默認的Shard數,請參見實例規格概述。當實例擴容后,擴容之前舊的DB對應的默認Shard數不會自動修改,需要根據實際情況修改Shard數,擴容后新建DB的Shard數為當前規格的默認數量。默認的Shard數是已經考慮擴容的場景,在資源擴容5倍以上的場景中,建議考慮重新設置Shard數,小于5倍的場景,無需修改也能帶來執行效率的提升。具體操作請參見Table Group設置最佳實踐

如下場景需要修改Shard數:

  • 擴容后,因業務需要,原有業務有規模增長,需要提高原有業務的查詢效率。此時,您需要創建新的Table Group,并為其設置更大的Shard數。原有的表和數據仍然在舊的Table Group中,您需要將數據重新導入新的Table Group中,完成Resharding的過程。

  • 擴容后,需要上線新業務,但已有業務并不變化。此時,建議您創建新的Table Group,并為其設置適合的Shard數,并不調整原有表的結構。

說明

一個DB內可以創建多個Table Group,但所有Table Group的Shard總數之和不應超過Hologres推薦的默認Shard數,這是對CPU資源的最有效利用。

JOIN場景優化

當有兩表或多表JOIN時,為了提高JOIN的性能,有如下幾種優化方式。

更新統計信息

如上述查看統計信息中,參與Join的表如果未及時更新統計信息,可能會導致數據量大的表做了Hash表,從而導致Join效率變低。因此可以通過更新表的統計信息,提升SQL性能。

analyze <tablename>;

選擇合適的分布列(Distribution Key)

分布列(Distribution Key)用于將數據劃分到多個Shard,劃分均衡可以避免數據傾斜。多個相關的表設計為相同的Distribution Key,可以起到Local Join的加速效果。創建表時,您可以通過如下原則選擇合適的分布列:

  • Distribution Key設置建議

    • 選擇Join查詢時的連接條件列作為分布列。

    • 選擇Group By頻繁的列作為分布列。

    • 選擇數據分布均勻離散的列作為分布列。

    • 更多關于Distribution Key的原理和使用詳情請參見分布鍵Distribution Key

  • 設置Distribution Key場景示例

    例如設置Distribution Key,表tmp和tmp1做Join,通過執行explain SQL語句看到執行計劃中有Redistribution Motion,說明數據有重分布,沒有Local Join,導致查詢效率比較低。您需要重新建表并同時設置Join Key為Distribution Key,避免多表連接時數據重分布帶來的額外開銷。motion重新建表后兩個表的DDL示例語句如下。

    begin;
    create table tmp(a int, b int, c int);
    call set_table_property('tmp', 'distribution_key', 'a');
    commit;
    
    begin;
    create table tmp1(a int, b int, c int);
    call set_table_property('tmp1', 'distribution_key', 'b');
    commit;
    
    -- 設置分布列為Join Key。
    select count(1) from tmp join tmp1 on tmp.a = tmp1.b ;

    通過重新設置表的Distribution Key,再次執行explain SQL語句,可以看到執行計劃中,紅框內的算子被優化掉了,數據按照相同的Hash Key分布于Shard中。因為數據分布相同,Motion算子被優化(上圖中紅框內的算子),表明數據不會重新分布,從而避免了冗余的網絡開銷。設置DK

使用Runtime Filter

從V2.0版本開始,Hologres開始支持Runtime Filter,通常應用在多表Join(至少2張表),尤其是大表Join小表的場景中,無需手動設置,優化器和執行引擎會在查詢時自動優化Join過程的過濾行為,使得掃描更少的數據量,從而降低IO開銷,以此提升Join的查詢性能,詳情請參見Runtime Filter

優化Join Order算法

  • 當SQL Join關系比較復雜時,或者Join的表多時,優化器(QO)消耗在連接關系最優選擇上的時間會更多,調整Join Order策略,在一定場景下會減少Query Optimization的耗時,設置優化器Join Order算法語法如下。

    set optimizer_join_order = '<value>'; 
  • 參數說明

    參數

    說明

    value

    優化器Join Order算法,有如下幾種。

    • exhaustive2(V2.2及以上版本默認值):升級優化的動態規劃算法。

    • exhaustive(早期版本默認值):通過動態規劃算法進行Join Order轉換,會生成最優的執行計劃,但優化器開銷最高。

    • query:不進行Join Order轉換,按照SQL書寫的連接順序執行,優化器開銷最低。

    • greedy:通過貪心算法進行Join Order的探索,優化器開銷適中。

  • 補充說明

    使用默認的exhaustive2算法可以全局探索最優的執行計劃,但對于很多表的Join(例如表數量大于10),優化耗時可能較高。使用query或者greedy算法可以減少優化器耗時,但無法生成最優的執行計劃。

優化Broadcast等Motion算子

目前Hologres包含四種Motion Node,分別對應四種數據重分布場景,如下表所示。

類型

描述

Redistribute Motion

數據通過哈希分布或隨機分布,Shuffle到一個或多個Shard。

Broadcast Motion

復制數據至所有Shard。

僅在Shard數量與廣播的表的數量均較少時,Broadcast Motion的優勢較大。

Gather Motion

匯總數據至一個Shard。

Forward Motion

用于聯邦查詢場景。外部數據源或執行引擎與Hologres執行引擎進行數據傳輸。

結合explain SQL語句執行結果您可以注意如下事項:

  • 如果Motion算子耗時較高,則您可以重新設計分布列。

  • 如果統計信息錯誤,導致生成Gather Motion或Broadcast Motion,則您可以通過analyze <tablename>命令將其修改為更高效的Redistribute Motion分布方式。

  • Broadcast Motion只有在Shard數較少,且廣播表的數量較少的場景下有優勢。所以如果是小表Broadcast的場景,建議您將表的Shard數量減少(盡量保持Shard Count與Worker數量成比例關系),從而提高查詢效率。Shard Count詳情請參見Shard Count

關閉Dictionary Encoding

對于字符類型(包括Text/Char/Varchar)的相關查詢,Dictionary Encoding或Decoding會減少比較字符串的耗時,但是會帶來大量的Decode或Encode開銷。

Hologres默認對所有的字符類型列建立Dictionary Encoding,您可以設置dictionary_encoding_columns為空,或關閉部分列的自動Dictionary Encoding功能。注意,修改Dictionary Encoding設置,會引起數據文件重新編碼存儲,會在一段時間內消耗一部分CPU和內存資源,建議在業務低峰期執行變更。

當Decode算子的耗時較高時,請關閉Decode。關閉Dictionary Encoding功能可以改善性能。

當表的字符類型字段較多時,按需選擇,可以不用將所有的字符類型都加入dictionary_encoding_columns。示例語句如下:

begin;
create table tbl (a int not null, b text not null, c int not null, d int);
call set_table_property('tbl', 'dictionary_encoding_columns', '');
commit;

常見的性能調優手段

可以通過優化相應的SQL來提高查詢效率。

采用Fixed Plan

Fixed Plan適用于高吞吐場景,通過簡化的執行路徑,實現數倍性能和吞吐的提升,配置方式和使用方法請參考Fixed Plan加速SQL執行

PQE算子改寫

Hologres底層有原生引擎HQE(Hologres Query Engine,向量引擎)和PQE(Postgres Query Engine,分布式Postgres引擎)等多個執行引擎,如果SQL語句中包含HQE不支持的算子,則系統會將該算子發送至PQE執行。此時查詢的性能未能足夠優化,需要修改相關查詢語句。

通過執行計劃(explain SQL)查詢,若執行計劃中出現External SQL(Postgres)則說明這部分的SQL是在PQE中執行的。

具體示例如下:HQE不支持not in,則會將not in操作轉到外部查詢引擎PQE執行。建議將not in重寫為not exists。優化前的SQL語句如下。

explain select * from tmp where a not in (select a from tmp1);

External算子代表該部分SQL語句是在外部引擎Postgres中執行的。post

優化后的SQL語句如下,不再使用外部查詢引擎。

explain select * from tmp where not exists (select a from tmp1 where a = tmp.a);

優化后的SQL

通過改寫函數,將算子運行在HQE引擎中,以下為函數改寫建議。同時Hologres每個版本都在不斷迭代PQE函數,以將更多函數下推至HQE。如果是HQE已經支持的函數,則可以通過升級版本來解決,詳情請參見函數功能發布記錄

Hologres原生引擎(HQE)不支持的函數

建議改寫的函數

樣例

備注

not in

not exists

select * from tmp where not exists (select a from tmp1 where a = tmp.a);

不涉及。

regexp_split_to_table(string text, pattern text)

unnest(string_to_array)

select name,unnest(string_to_array(age,',')) from demo;

regexp_split_to_table支持正則表達式。

Hologres V2.0.4版本起HQE支持regexp_split_to_table,需要使用如下命令開啟GUC:set hg_experimental_enable_hqe_table_function = on;

substring

extract(hour from to_timestamp(c1, 'YYYYMMDD HH24:MI:SS'))

select cast(substring(c1, 13, 2) as int) AS hour from t2;

改寫為:

select extract(hour from to_timestamp(c1, 'YYYYMMDD HH24:MI:SS')) from t2;

Hologres部分V0.10版本及更早版本不支持substring。V1.3版本及以上版本中,HQE已支持substring函數的非正則表達式入參。

regexp_replace

replace

select regexp_replace(c1::text,'-','0') from t2;

改寫為:

select replace(c1::text,'-','') from t2;

replace不支持正則表達式。

at time zone 'utc'

刪除at time zone 'utc'

select date_trunc('day',to_timestamp(c1, 'YYYYMMDD HH24:MI:SS')  at time zone 'utc') from t2

改寫為:

select date_trunc('day',to_timestamp(c1, 'YYYYMMDD HH24:MI:SS') ) from t2;

不涉及。

cast(text as timestamp)

to_timestamp

select cast(c1 as timestamp) from t2;

改寫為:

select to_timestamp(c1, 'yyyyMMdd hh24:mi:ss') from t2;

Hologres V2.0版本起HQE支持。

timestamp::text

to_char

select c1::text from t2;

改寫為:

select to_char(c1, 'yyyyMMdd hh24:mi:ss') from t2;

Hologres V2.0版本起HQE支持。

避免模糊查詢

模糊查詢(Like操作)不會建立索引。

結果緩存對查詢的影響

Hologres會默認對相同的查詢或子查詢結果進行緩存,重復執行會命中緩存結果。您可以使用如下命令關閉緩存對性能測試的影響:

set hg_experimental_enable_result_cache = off;

OOM的優化手段

當實例計算內存不足時通常會出現OOM,常見的報錯如下。產生OOM的原因有多種,比如計算復雜、并發量高等,可以根據不同的原因進行針對性優化,從而減少OOM。詳情請參見OOM常見問題排查指南

Total memory used by all existing queries exceeded memory limitation. 
memory usage for existing queries=(2031xxxx,184yy)(2021yyyy,85yy)(1021121xxxx,6yy)(2021xxx,18yy)(202xxxx,14yy); Used/Limit: xy1/xy2 quota/sum_quota: zz/100

Order By Limit場景優化

在Hologres V1.3之前版本,對Order By Limit場景不支持Merge Sort算子,生成執行計劃時,在最后輸出時還會做一次排序,導致性能相對較差。從1.3版本開始,引擎通過對Order By Limit場景優化,支持Merge Sort算子,實現多路歸并排序,無需再進行額外的排序,提升了查詢性能。

優化示例如下。

  • 建表DDL

  • begin;
    create table test_use_sort_1
    (
              uuid           text not null,
              gpackagename   text not null,
              recv_timestamp text not null
    );
    call set_table_property('test_use_sort_1', 'orientation', 'column');
    call set_table_property('test_use_sort_1', 'distribution_key', 'uuid');
    call set_table_property('test_use_sort_1', 'clustering_key', 'uuid:asc,gpackagename:asc,recv_timestamp:desc');
    commit;
    
    --插入數據
    insert into test_use_sort_1 select i::text, i::text, '20210814' from generate_series(1, 10000) as s(i);
    
    --更新統計信息
    analyze test_use_sort_1;
  • 查詢命令

  • set hg_experimental_enable_reserve_gather_exchange_order =on 
    set hg_experimental_enable_reserve_gather_motion_order =on
    select uuid from test_use_sort_1 order by uuid limit 5;
  • 執行計劃對比

    • Hologres V1.3之前版本(V1.1)的執行計劃如下。執行計劃1.1

    • Hologres V1.3版本的執行計劃如下。執行計劃1.3

  • 從執行計劃對比中可以看出,Hologres V1.3版本在最后輸出會少一個排序,直接多路歸并,提升了查詢性能。

Count Distinct優化

  • 改寫為APPROX_COUNT_DISTINCT

    Count Distinct是精確去重,需要把相同key的記錄shuffle到同一個節點去重,比較耗費資源。Hologres實現了擴展函數APPROX_COUNT_DISTINCT,采用HyperLogLog基數估計的方式進行非精確的COUNT DISTINCT計算,提升查詢性能。誤差率平均可以控制在0.1%-1%以內,可以根據業務情況適當改寫,詳情請參見APPROX_COUNT_DISTINCT

  • 使用UNIQ函數

    Hologres從 V1.3版本開始,支持UNIQ精確去重函數,在GROUP BY KEY的KEY基數較高時,比Count Distinct性能更好,更節省內存。當使用Count Distinct出現OOM時,可以使用UNIQ做替換,詳情請參見UNIQ

  • 設置合適的Distribution Key

    當有多個Count Distinct且是key是同一個并且數據離散均勻分布,建議將Count Distinct的key設置成Distribution Key,這樣相同的數據可以分布相同的Shard,避免數據Shuffle。

  • Count Distinct優化

    Hologres從V2.1版本開始,針對Count Distinct場景做了非常多的性能優化(包括單個Count Distinct、多個Count Distinct、數據傾斜、SQL沒有Group By字段等場景),無需手動改寫成UNIQ,即可實現更好的性能。如果想要提升Count Distinct性能,建議您將Hologres實例升級至V2.1及以上版本。

Group By優化

Group By Key會導致數據在計算時按照分組列的Key重新分布數據,如果Group By耗時較高,您可以將Group By的列設置為分布列。

-- 數據如果按照a列的值進行分布,將減少數據運行時重分布,充分利用shard的并行計算能力。
select a, count(1) from t1 group by a; 

數據傾斜處理

數據在多個Shard上分布不均勻會導致查詢速度較慢,您可以通過如下語句判斷數據分布是否存在傾斜。詳情請參見查看Worker傾斜關系

-- hg_shard_id是每個表的內置隱藏列,描述對應行數據所在shard
select hg_shard_id, count(1) from t1 group by hg_shard_id;
  • 如果數據存在顯著傾斜,則需要更改distribution_key,選擇數據分布均勻離散的列作為分布列。

    說明

    更改distribution_key需要重新創建表并導入數據。

  • 如果數據本身存在傾斜(與distribution_key無關時),建議從業務角度對數據進行優化,避免傾斜。

With表達式優化(Beta)

Hologres兼容PostgreSQL ,支持CTE(Common Table Expression),常用在with遞歸查詢,其實現原理同PostgreSQL,都是基于Inlining展開的,所以當有多次使用CTE時會造成重復計算。在HologresV1.3版本中,可以通過如下GUC參數支持CTE Reuse(復用),這樣CTE只需計算一次而被多次引用,用以節省計算資源,提升查詢性能。若您的Hologres實例版本低于 V1.3,請升級實例。

set optimizer_cte_inlining=off;
說明
  • 該功能當前還處于Beta階段,默認沒有開啟(默認會將CTE全部Inline展開,重復計算),可手動設置GUC后開啟使用。

  • CTE Reuse開啟后,依賴Shuffle階段的Spill功能,因為下游用戶消費CTE的進度是不同步的,所以數據量大的時候會影響性能。

  • 示例

    create table cte_reuse_test_t
    (
        a integer not null,
        b text,
        primary key (a)
    );
    
    insert into cte_reuse_test_t values(1, 'a'),(2, 'b'), (3, 'c'), (4, 'b'), (5, 'c'), (6, ''), (7, null);
    
    
    set optimizer_cte_inlining=off;
    
    explain with c as (select b, max(a) as a from cte_reuse_test_t group by b)
    select a1.a,a2.a,a1.b, a2.b
    from c a1, c a2
    where a1.b = a2.b
    order by a1.b
    limit 100;
                                        
  • 執行計劃對比

    • Hologres V1.3之前版本(V1.1)的執行計劃如下。執行計劃_11with

    • Hologres V1.3版本的執行計劃如下。執行計劃_13with

    從執行計劃的對比中可以看出Hologres V1.3之前版本會有多個AGG計算(HashAggregate),Hologres V1.3版本只需計算一次就被結果復用,提升了性能。

單階段Agg優化為多階段Agg

如果Agg算子耗時過高,您可以檢查是否沒有做Local Shard級別的預聚合。

通過在單個Shard內先進行本地的Agg操作,可以減少最終聚合操作的數據量,提升性能。具體如下:

  • 三階段聚合:數據先進行文件級別的聚合計算,再聚合單個Shard內的數據,最后匯總所有Shard的結果。三階段聚合

  • 兩階段聚合:數據先在單個Shard內進行聚合計算,再匯總所有Shard的結果。兩階段聚合

您可以強制Hologres進行多階段聚合操作,語句如下。

set optimizer_force_multistage_agg = on;

建表屬性優化

選擇存儲類型

Hologres支持行存儲、列存儲和行列共存多種存儲模式,您可以根據業務場景選擇合適的存儲類型,如下表所示。

類型

適用場景

缺點

行存儲

  • 按主鍵進行高QPS的點查詢場景。

  • 一次能讀取所有列,并且對UPDATE、DELETE及INSERT操作的性能較好。

大范圍的查詢、全表掃描及聚合等操作性能較差。

列存儲

適用于多列按范圍查詢、單表聚合及多表連接等數據分析場景。

UPDATE和DELETE操作及無索引場景下的點查詢性能慢于行存儲。

行列共存

同時具備以上行列兩種使用場景。

存儲開銷更高。

選擇數據類型

Hologres支持多種數據類型,您可以根據業務場景以及需求選擇合適的數據類型,原則如下:

  • 盡量選用存儲空間小的類型。

    • 優先使用INT類型,而不是BIGINT類型。

    • 優先使用精確確定的DECIMAL/NUMERIC類型,明確數值精度(PRECISION,SCALE),且精度盡量小,減少使用FLOAT/DOUBLE PRECISION等非精確類型,避免統計匯總中的誤差。

    • GROUP BY的列不建議使用FLOAT/DOUBLE等非精確類型。

    • 優先使用TEXT,適用范圍更廣,當使用VARCHAR(N)CHAR(N),N的取值盡量小。

    • 日期類型使用TIMESTAMPTZ、DATE,避免使用TEXT。

  • 關聯條件使用一致的數據類型。

    進行多表關聯時,不同列盡量使用相同的數據類型。避免Hologres將不同類型的列進行隱式類型轉換,造成額外的開銷。

  • UNION或GROUP BY等操作避免使用FLOAT/DOUBLE等非精確類型。

    UNION或GROUP BY等操作暫不支持DOUBLE PRECISION和FLOAT數據類型,需要使用DECIMAL類型。

選擇主鍵

主鍵(Primary Key)主要用于保證數據的唯一性,適用于主鍵重復的導入數據場景。您可以在導入數據時設置option選擇去重方式,如下所示:

  • ignore:忽略新數據。

  • update:新數據覆蓋舊數據。

合理的設置主鍵能幫助優化器在某些場景下生成更好的執行計劃。例如,查詢為group by pk,a,b,c的場景。

但是在列存儲場景,主鍵的設置對于寫入數據的性能會有較大的影響。通常,不設置主鍵的寫入性能是設置主鍵的3倍。

選擇分區表

Hologres當前僅支持創建一級分區表。合理的設置分區會加速查詢性能,不合理的設置(比如分區過多)會造成小文件過多,查詢性能顯著下降。

說明

對于按天增量導入的數據,建議按天建成分區表,數據單獨存儲,只訪問當天數據。

設置分區適用的場景如下:

  • 刪除整個子表的分區,不影響其他分區數據。DROP/TRUNCATE語句的性能高于DELETE語句。

  • 對于分區列在謂詞條件中的查詢,可以直接通過分區列索引到對應分區,并且可以直接查詢子分區,操作更為靈活。

  • 對于周期性實時導入的數據,適用于創建分區表。例如,每天都會導入新的數據,可以將日期作為分區列,每天導入數據至一個子分區。示例語句如下。

  • begin;
    create table insert_partition(c1 bigint not null, c2 boolean, c3 float not null, c4 text, c5 timestamptz not null) partition by list(c4);
    call set_table_property('insert_partition', 'orientation', 'column');
    commit;
    create table insert_partition_child1 partition of insert_partition for values in('20190707');
    create table insert_partition_child2 partition of insert_partition for values in('20190708');
    create table insert_partition_child3 partition of insert_partition for values in('20190709');
    
    select * from insert_partition where c4 >= '20190708';
    select * from insert_partition_child3;

選擇索引

Hologres支持設置多種索引,不同索引的作用不同。您可以根據業務場景選擇合適的索引,提升查詢性能,因此寫入數據前,請根據業務場景提前設計好表結構。索引類型如下表所示。

類型

名稱

描述

使用建議

示例查詢語句

clustering_key

聚簇列

文件內聚簇索引,數據在文件內按該索引排序。

對于部分范圍查詢,Hologres可以直接通過聚簇索引的數據有序屬性進行過濾。

將范圍查詢或Filter查詢列作為聚簇索引列。索引過濾具備左匹配原則,建議設置不超過2列。

select sum(a) from tb1 where a > 100 and a < 200;

bitmap_columns

位圖列

文件內位圖索引,數據在文件內按該索引列建立位圖。

對于等值查詢,Hologres可以按照數值對每一行的數據做編碼,通過位操作快速索引到對應行,時間復雜度為O(1)。

將等值查詢列作為Bitmap列。

select * from tb1 where a =100;

segment_key(也稱為event_time_column)

分段列

文件索引,數據按Append Only方式寫入文件,隨后文件間按該索引鍵合并小文件。

Segment_key標識了文件的邊界范圍,您可以通過Segment Key快速索引到目標文件。

Segment_key是為時間戳、日期等有序,范圍類數據場景設計的,因此與數據的寫入時間有強相關性。

您需要先通過Segment_key進行快速過濾,再通過Bitmap或Cluster索引進行文件內范圍或等值查詢。具備最左匹配原則,一般只有1列。

建議將第一個非空的時間戳字段設置為Segment_key。

select sum(a) from tb1 where ts > '2020-01-01' and a < '2020-03-02';

clustering_key和segment_key都需要滿足傳統數據庫(例如MySQL)的最左前綴匹配原則,即按照Index書寫的最左列排序進行索引。如果最左列為有序的場景,則按照左邊第二列進行排序。示例如下。

call set_table_property('tmp', 'clustering_key', 'a,b,c');
select * from tmp where a > 1 ;  --可以使用Cluster索引。
select * from tmp where a > 1 and c > 2 ;   --只有a可以使用Cluster索引。
select * from tmp where a > 1 and b > 2 ;  --a,b均可以使用Cluster索引。
select * from tmp where a > 1 and b > 2 and c > 3 ; --a,b,c均可以使用Cluster索引。
select * from tmp where b > 1 and c > 2 ;   --b,c均不能使用Cluster索引。

Bitmap Index支持多個列的and或or查詢,示例如下。

call set_table_property('tmp', 'bitmap_columns', 'a,b,c');
select * from tmp where a = 1 and b = 2 ;  -- 可以使用Bitmap索引。
select * from tmp where a = 1 or b = 2 ; -- 可以使用Bitmap索引。
說明

bitmap_columns可以在創建表后添加,clustering_key和segment_key則在創建表時已經指定,后續無法再添加。

查看是否使用Index

創建tmp表并指定索引字段,語句如下。

begin;
create table tmp(a int not null, b int not null, c int not null);
call set_table_property('tmp', 'clustering_key', 'a');
call set_table_property('tmp', 'segment_key', 'b');
call set_table_property('tmp', 'bitmap_columns', 'a,b,c');
commit;
  • 查看是否使用Cluster Index,語句如下。

    explain select * from tmp where a > 1;

    cluster

  • 查看是否使用Bitmap Index,語句如下。

    explain select * from tmp where c = 1;

    bitmap

  • 查看是否使用Segment Key,語句如下。

    explain select * from tmp where b > 1;

    segment