一文讀懂autoanalyze使用【這次高斯不是數(shù)學(xué)家】

      網(wǎng)友投稿 1062 2022-05-30

      analyze執(zhí)行的是否及時,在一定程度上直接決定了SQL執(zhí)行的快慢。因此,GaussDB(DWS)引入了自動統(tǒng)計信息收集,可以做到讓用戶不再擔(dān)心統(tǒng)計信息是否過期。

      1. 自動收集場景

      需要進(jìn)行自動統(tǒng)計信息收集的場景通常有五個:批量DML結(jié)束時,增量DML結(jié)束時,DDL結(jié)束時,查詢開始時和后臺定時任務(wù)。

      INSERT,UPDATE,DELETE,UPSERTCOPY,MERGE

      所以,為了避免對DML,DDL帶來不必要的性能開銷和死鎖風(fēng)險,我們選擇了在查詢開始前觸發(fā)analzye。

      2. 自動收集原理

      GaussDB(DWS)在SQL執(zhí)行過程中,會記錄表增刪改查相關(guān)的運行時統(tǒng)計信息,并在事務(wù)提交或回滾后記錄到共享的內(nèi)存種。

      這些信息可以通過 “pg_stat_all_tables視圖” 查詢,也可以通過下面函數(shù)進(jìn)行查詢。

      pg_stat_get_tuples_inserted --表累積insert條數(shù) pg_stat_get_tuples_updated --表累積update條數(shù) pg_stat_get_tuples_deleted --表累積delete條數(shù) pg_stat_get_tuples_changed --表自上次analyze以來,修改的條數(shù) pg_stat_get_last_analyze_time --查詢最近一次analyze時間

      因此,根據(jù)共享內(nèi)存中 "表自上次analyze以來修改過的條數(shù)" 是否超過一定閾值,就可以判定是否需要做analyze了。

      3. 自動收集閾值

      3.1 全局閾值

      autovacuum_analyze_threshold #表觸發(fā)analyze的最小修改量 autovacuum_analyze_scale_factor #表觸發(fā)analyze時的修改百分比

      當(dāng)"表自上次analyze以來修改的條數(shù)" >= autovacuum_analyze_threshold + 表估算大小 * autovacuum_analyze_scale_factor時,需要自動觸發(fā)analyze。

      3.2 表級閾值

      --設(shè)置表級閾值 ALTER TABLE item SET (autovacuum_analyze_threshold=50); ALTER TABLE item SET (autovacuum_analyze_scale_factor=0.1); --查詢閾值 postgres=# select pg_options_to_table(reloptions) from pg_class where relname='item'; pg_options_to_table --------------------------------------- (autovacuum_analyze_threshold,50) (autovacuum_analyze_scale_factor,0.1) (2 rows) --重置閾值 ALTER TABLE item RESET (autovacuum_analyze_threshold); ALTER TABLE item RESET (autovacuum_analyze_scale_factor);

      不同表的數(shù)據(jù)特征不一樣,需要觸發(fā)analyze的閾值可能有不同的需求。表級閾值優(yōu)先級高于全局閾值。

      3.3 查看表的修改量是否超過了閾值(僅當(dāng)前CN)

      postgres=# select pg_stat_get_local_analyze_status('t_analyze'::regclass); pg_stat_get_local_analyze_status ---------------------------------- Analyze not needed (1 row)

      4. 自動收集方式

      GaussDB(DWS)提供了三種場景下表的自動分析。

      當(dāng)查詢中存在“統(tǒng)計信息完全缺失”或“修改量達(dá)到analyze閾值”的表,且執(zhí)行計劃不采取FQS (Fast Query Shipping)執(zhí)行時,則通過autoanalyze控制此場景下表統(tǒng)計信息的自動收集。此時,查詢語句會等待統(tǒng)計信息收集成功后,生成更優(yōu)的執(zhí)行計劃,再執(zhí)行原查詢語句。

      當(dāng)autovacuum設(shè)置為on時,系統(tǒng)會定時啟動autovacuum線程,對“修改量達(dá)到analyze閾值”的表在后臺自動進(jìn)行統(tǒng)計信息收集。

      6.凍結(jié)統(tǒng)計信息

      6.1 凍結(jié)表的distinct值

      當(dāng)一個表的distinct總是估算不準(zhǔn),例如:數(shù)據(jù)扎堆兒重復(fù)場景。如果表的distinct值固定,可以通過以下方式凍結(jié)表的distinct值。

      postgres=# alter table lineitem alter l_orderkey set (n_distinct=0.9); ALTER TABLE postgres=# select relname,attname,attoptions from pg_attribute a,pg_class c where c.oid=a.attrelid and attname='l_orderkey'; relname | attname | attoptions ----------+------------+------------------ lineitem | l_orderkey | {n_distinct=0.9} (1 row) postgres=# alter table lineitem alter l_orderkey reset (n_distinct); ALTER TABLE postgres=# select relname,attname,attoptions from pg_attribute a,pg_class c where c.oid=a.attrelid and attname='l_orderkey'; relname | attname | attoptions ----------+------------+------------ lineitem | l_orderkey | (1 row)

      6.2. 凍結(jié)表的全部統(tǒng)計信息

      如果表的數(shù)據(jù)特征基本不變,還可以凍結(jié)表的統(tǒng)計信息,來避免重復(fù)進(jìn)行analyze。

      alter table table_name set frozen_stats=true;

      7. 手動查看表是否需要做analyze

      a. 不想在業(yè)務(wù)高峰期時觸發(fā)數(shù)據(jù)庫后臺任務(wù),所以不愿意打開autovacuum來觸發(fā)analyze,怎么辦?

      b. 業(yè)務(wù)修改了一批表,想立即對這些表馬上做一次analyze,又不知道都有哪些表,怎么辦?

      c. 業(yè)務(wù)高峰來臨前想對臨近閾值的表都做一次analyze,怎么辦?

      我們將autovacuum檢查閾值判斷是否需要analyze邏輯,抽取成了函數(shù),幫助用戶靈活主動的檢查哪些表需要做analyze。

      7.1 判斷表是否需要analyze(串行版,適用于所有歷史版本)

      -- the function for get all pg_stat_activity information in all CN of current cluster. CREATE OR REPLACE FUNCTION pg_catalog.pgxc_stat_table_need_analyze(in table_name text) RETURNS BOOl AS $$ DECLARE row_data record; coor_name record; fet_active text; fetch_coor text; relTuples int4; changedTuples int4:= 0; rel_anl_threshold int4; rel_anl_scale_factor float4; sys_anl_threshold int4; sys_anl_scale_factor float4; anl_threshold int4; anl_scale_factor float4; need_analyze bool := false; BEGIN --Get all the node names fetch_coor := 'SELECT node_name FROM pgxc_node WHERE node_type=''C'''; FOR coor_name IN EXECUTE(fetch_coor) LOOP fet_active := 'EXECUTE DIRECT ON (' || coor_name.node_name || ') ''SELECT pg_stat_get_tuples_changed(oid) from pg_class where relname = ''''|| table_name ||'''';'''; FOR row_data IN EXECUTE(fet_active) LOOP changedTuples = changedTuples + row_data.pg_stat_get_tuples_changed; END LOOP; END LOOP; EXECUTE 'select pg_stat_get_live_tuples(oid) from pg_class c where c.oid = '''|| table_name ||'''::REGCLASS;' into relTuples; EXECUTE 'show autovacuum_analyze_threshold;' into sys_anl_threshold; EXECUTE 'show autovacuum_analyze_scale_factor;' into sys_anl_scale_factor; EXECUTE 'select (select option_value from pg_options_to_table(c.reloptions) where option_name = ''autovacuum_analyze_threshold'') as value from pg_class c where c.oid = '''|| table_name ||'''::REGCLASS;' into rel_anl_threshold; EXECUTE 'select (select option_value from pg_options_to_table(c.reloptions) where option_name = ''autovacuum_analyze_scale_factor'') as value from pg_class c where c.oid = '''|| table_name ||'''::REGCLASS;' into rel_anl_scale_factor; --dbms_output.put_line('relTuples='||relTuples||'; sys_anl_threshold='||sys_anl_threshold||'; sys_anl_scale_factor='||sys_anl_scale_factor||'; rel_anl_threshold='||rel_anl_threshold||'; rel_anl_scale_factor='||rel_anl_scale_factor||';'); if rel_anl_threshold IS NOT NULL then anl_threshold = rel_anl_threshold; else anl_threshold = sys_anl_threshold; end if; if rel_anl_scale_factor IS NOT NULL then anl_scale_factor = rel_anl_scale_factor; else anl_scale_factor = sys_anl_scale_factor; end if; if changedTuples > anl_threshold + anl_scale_factor * relTuples then need_analyze := true; end if; return need_analyze; END; $$ LANGUAGE 'plpgsql';

      7.2 判斷表是否需要analyze(并行版,適用于支持并行執(zhí)行框架的版本)

      -- the function for get all pg_stat_activity information in all CN of current cluster. --SELECT sum(a) FROM pg_catalog.pgxc_parallel_query('cn', 'SELECT 1::int FROM pg_class LIMIT 10') AS (a int); 利用并發(fā)執(zhí)行框架 CREATE OR REPLACE FUNCTION pg_catalog.pgxc_stat_table_need_analyze(in table_name text) RETURNS BOOl AS $$ DECLARE relTuples int4; changedTuples int4:= 0; rel_anl_threshold int4; rel_anl_scale_factor float4; sys_anl_threshold int4; sys_anl_scale_factor float4; anl_threshold int4; anl_scale_factor float4; need_analyze bool := false; BEGIN --Get all the node names EXECUTE 'SELECT sum(a) FROM pg_catalog.pgxc_parallel_query(''cn'', ''SELECT pg_stat_get_tuples_changed(oid)::int4 from pg_class where relname = ''''|| table_name ||'''';'') AS (a int4);' into changedTuples; EXECUTE 'select pg_stat_get_live_tuples(oid) from pg_class c where c.oid = '''|| table_name ||'''::REGCLASS;' into relTuples; EXECUTE 'show autovacuum_analyze_threshold;' into sys_anl_threshold; EXECUTE 'show autovacuum_analyze_scale_factor;' into sys_anl_scale_factor; EXECUTE 'select (select option_value from pg_options_to_table(c.reloptions) where option_name = ''autovacuum_analyze_threshold'') as value from pg_class c where c.oid = '''|| table_name ||'''::REGCLASS;' into rel_anl_threshold; EXECUTE 'select (select option_value from pg_options_to_table(c.reloptions) where option_name = ''autovacuum_analyze_scale_factor'') as value from pg_class c where c.oid = '''|| table_name ||'''::REGCLASS;' into rel_anl_scale_factor; dbms_output.put_line('relTuples='||relTuples||'; sys_anl_threshold='||sys_anl_threshold||'; sys_anl_scale_factor='||sys_anl_scale_factor||'; rel_anl_threshold='||rel_anl_threshold||'; rel_anl_scale_factor='||rel_anl_scale_factor||';'); if rel_anl_threshold IS NOT NULL then anl_threshold = rel_anl_threshold; else anl_threshold = sys_anl_threshold; end if; if rel_anl_scale_factor IS NOT NULL then anl_scale_factor = rel_anl_scale_factor; else anl_scale_factor = sys_anl_scale_factor; end if; if changedTuples > anl_threshold + anl_scale_factor * relTuples then need_analyze := true; end if; return need_analyze; END; $$ LANGUAGE 'plpgsql';

      7.3 判斷表是否需要analyze(自定義閾值)

      一文讀懂a(chǎn)utoanalyze使用【這次高斯不是數(shù)學(xué)家】

      -- the function for get all pg_stat_activity information in all CN of current cluster. CREATE OR REPLACE FUNCTION pg_catalog.pgxc_stat_table_need_analyze(in table_name text, int anl_threshold, float anl_scale_factor) RETURNS BOOl AS $$ DECLARE relTuples int4; changedTuples int4:= 0; need_analyze bool := false; BEGIN --Get all the node names EXECUTE 'SELECT sum(a) FROM pg_catalog.pgxc_parallel_query(''cn'', ''SELECT pg_stat_get_tuples_changed(oid)::int4 from pg_class where relname = ''''|| table_name ||'''';'') AS (a int4);' into changedTuples; EXECUTE 'select pg_stat_get_live_tuples(oid) from pg_class c where c.oid = '''|| table_name ||'''::REGCLASS;' into relTuples; if changedTuples > anl_threshold + anl_scale_factor * relTuples then need_analyze := true; end if; return need_analyze; END; $$ LANGUAGE 'plpgsql';

      通“優(yōu)化器觸發(fā)的實時analyze”和“后臺autovacuum觸發(fā)的輪詢analyze”,GaussDB(DWS)已經(jīng)可以做到讓用戶不再關(guān)心表是否需要analyze。建議在最新版本中試用。

      征文活動

      【這次高斯不是數(shù)學(xué)家】有獎?wù)魑幕馃徇M(jìn)行中:https://bbs.huaweicloud.com/blogs/345260

      GaussDB數(shù)據(jù)庫 云端實踐 數(shù)據(jù)倉庫服務(wù) GaussDB(DWS)

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實后本網(wǎng)站將在24小時內(nèi)刪除侵權(quán)內(nèi)容。

      上一篇:云化測試七種武器(下)
      下一篇:《TCP/IP詳解 卷2:實現(xiàn)》 —1.6 系統(tǒng)調(diào)用和庫函數(shù)
      相關(guān)文章
      亚洲AV成人精品一区二区三区| 亚洲日韩精品国产3区| 精品久久亚洲一级α| 在线aⅴ亚洲中文字幕| 国产成人精品日本亚洲专| 亚洲日韩在线视频| 亚洲精品美女久久久久9999| 亚洲黄网在线观看| 亚洲成在人线中文字幕| 亚洲剧情在线观看| 亚洲an日韩专区在线| 亚洲最大的成人网| 亚洲精品无码av中文字幕| 亚洲AV无码AV吞精久久| 成人亚洲综合天堂| 亚洲日韩在线观看| 亚洲人成图片小说网站| 亚洲国产精品综合久久2007| 亚洲爆乳成av人在线视菜奈实| 亚洲AV成人影视在线观看| 亚洲综合中文字幕无线码| 中文字幕无码亚洲欧洲日韩| 亚洲日韩国产欧美一区二区三区 | 国产亚洲综合精品一区二区三区| 337P日本欧洲亚洲大胆艺术图 | 色窝窝亚洲AV网在线观看| 国产成人亚洲综合在线| 亚洲国产免费综合| 亚洲中文字幕无码永久在线| 亚洲av永久无码精品表情包| 蜜芽亚洲av无码精品色午夜| 亚洲国产中文在线二区三区免| tom影院亚洲国产一区二区| 亚洲人成色777777老人头| 国产亚洲视频在线观看网址| 在线精品亚洲一区二区三区| 日韩va亚洲va欧洲va国产| 亚洲精品福利网泷泽萝拉| 亚洲中文无码线在线观看| 亚洲欧美成人综合久久久| 亚洲第一黄色网址|