1.查看數據庫中大於100MB的表的傾斜情況
(數據傾斜率公式:最大子節點數據量/平均節點數據量。為避免整張表的數據量為空,同時對結果的影響很小,在平均節點數據量基礎上加上一個很小的值)
SELECT table_name,max_div_avg,pg_size_pretty(total_size) table_size FROM ( SELECT table_name, MAX(size)/(AVG(size)+0.001) AS max_div_avg, CAST(SUM(size) AS BIGINT) total_size FROM (SELECT gp_segment_id, oid::regclass table_name, pg_relation_size(oid) size FROM gp_dist_random('pg_class') WHERE relkind='r' AND relstorage IN ('a','h')) t GROUP BY table_name)tab WHERE total_size >= 104857600 ORDER BY total_size DESC;
2.隊列限制,執行和等待查詢的數量:
select * from pg_resqueue_status
3.查看role分配的resource queue
SELECT rolname, rsqname FROM pg_roles, pg_resqueue WHERE pg_roles.rolresqueue=pg_resqueue.oid;
4.查詢所有的resource queue的當前活動sql
SELECT usename, rsqname, locktype, objid, transaction, pid, mode, granted, waiting FROM pg_stat_activity, pg_resqueue, pg_locks WHERE pg_stat_activity.procpid=pg_locks.pid AND pg_locks.objid=pg_resqueue.oid;
5.各主、鏡像節點存放的文件系統路徑
select * from pg_filespace_entry;
6.查看數據庫空間大小
SELECT *,pg_size_pretty(sodddatsize) dbsize FROM gp_toolkit.gp_size_of_database ORDER BY sodddatsize desc;
7.查看活動語句的優先級
select *from gp_toolkit.gp_resq_priority_statement;
8.查看鎖信息
SELECT locktype, database, c.relname, l.relation, l.transactionid, l.transaction, l.pid, l.mode, l.granted, a.current_query FROM pg_locks l, pg_class c, pg_stat_activity a WHERE l.relation=c.oid AND l.pid=a.procpid ORDER BY c.relname;
9.修改某個數據庫為只讀狀態(要求管理員權限)
alter database mp_mvt set default_transaction_read_only= on ;
10.查看哪些節點掛了
select *from gp_segment_configuration where status = 'd';
11.當前數據庫使用狀態
select * from pg_stat_database;
12.查看GP對應的PostgreSQL版本信息
SELECT VERSION();
/*
部分GP優化總結:
not in==》改用left join去重后的表關聯來實現
cost:返回第一行記錄前的啟動時間,和返回所有記錄的總時間(以磁盤頁面存取為單位計量)
rows:根據統計信息估計SQL返回結果集的行數
width:返回的結果集的每一行的長度,這個長度值是根據pg_statistic表中的統計信息來計算的
hash join: 先對其中一張關聯的表計算hash值,在內存中用一個散列表保存,然后對另外一張表進行全表掃描,之后將每一行與這個散列表進行關聯。
nestedloop:關聯的兩張表中的數據量比較小的表進行廣播,如笛卡爾積:select * fromtest1,test2
merge join:將兩張表按照關聯鍵進行排序,然后按照歸並排序的方式將數據進行關聯,效率比hash join差。full outer join只能采用merge join來實現。
哈希關聯 - 用關聯字段做哈希鍵,對小表建立哈希表。然后掃描大表,計算大表每行關聯字段的哈希鍵,從哈希表中查找哈希值相同的行。通常哈希關聯是速度最快的關聯方式。解釋計划中的Hash Cond是關聯字段。
嵌套循環 - 遍歷大數據集,對其每一行,掃描小數據集,並找到匹配的行。嵌套循環關聯需要廣播一個表的數據,以便另一個表的數據可以和該表的每一行進行比較。對於小表或者使用索引的表性能良好。也用於笛卡爾關聯和范圍關聯。對大表使用嵌套關聯性能不佳。如果查詢節點使用嵌套循環關聯操作符,則檢查SQL,確保結果是期望的。設置配置參數enable_nestloop 為 OFF (默認)以優先使用哈希關聯。
合並關聯 - 對兩個數據集排序,然后合並。合並關聯對已經排序的數據性能很好,但是較少使用。如要使用合並關聯,設置 enable_mergejoin 為 ON。
關聯鍵強制類型轉換
一般,表按照指定的分布鍵作hash分部。如果兩個表按照id:intege、id:numericr分布,關聯時,需要有一個表id作強制類型轉化,因為不同類型的hash值不一樣,因而導致數據重分布。
關聯鍵與分部鍵不一致
group by、開窗函數、grouping sets會引發重分布
1、批量數據處理后,無論成功與否,都應該進行vaccumanalyze <table_name>.
2、對於大表的DISTINCT操作,請用 GROUPBY操作進行替代
3、對於大表的UNION操作,請用UNIONALL 加 group by進行改寫
4、嵌套查詢操作,盡量改寫成連接查詢操作
5、大表更新操作,盡量通過外連接+插入+truncate進行替代
6、大表刪除操作,盡量通過外連接+插入+truncate進行替代
7、盡量避免進行存儲過程函數嵌套導致鎖沖突,考慮使用其它語言進行總體調度,比如shell,Java,c等。
8、盡量避免在數據庫中使用序列,游標, 循環,考慮對數據進行整體操作。
9、避免高度頻繁的建表刪表操作,容易造成字典破碎和字典鎖的問題,因此可以通過臨時表和其它語言方式替代。
11、檢查大表的hash鍵定義是否可以保證每個segment存儲均勻,數據處理均勻,以及大表連接操作過程中可以盡量避免motion操作。從目前業務看,可以考慮客戶ID, 電話號碼作為首選的hash鍵,然后進行檢查。
12、為了加快開發進度,減少開發時的彼此影響,建議每個開發人員裝一個gp虛擬機,相關表放入少量記錄,進行單步測試。通過單步測試后,統一提交到測試服務器上進行聯合測試和壓力測試。
13、運行較大操作時,不建議使用pgadmin完成操作,建議寫成shell腳本在后台進行測試。避免頻繁不正常中斷操作,對整個開發產生影響
14、盡量避免不正常中斷操作,如需不正常中斷操作,請使用函數pg_cancel_backend函數,並耐心等待3~5分鍾,再繼續相關操作,避免造成數據字典破壞。
聚合函數太多:
一條SQL中聚合函數太多,而且可能由於統計信息不夠詳細或者SQL太負責,錯選hashaggregate來執行,導致內存不足。解決方法:
拆分成多個SQL來執行,減少hashaggregate使用的內存執行enable_hashagg=off,把hashaggregate參數關掉,強制不采用。將會采用groupaggregate,這樣排序時間會長一些,但是內存可控,建議采用這種方式比較簡單。
資源隊列:
數據寫入、查詢分別使用不同的用戶,GP創建用戶時為不同用戶指定不同的資源隊列。
其它優化技巧:
用group by對distinct改寫,因為DISTINCT要進行排序操作用UNION ALL加GROUP BY的方式對UNION改寫盡量使用GREENPLUM自身提供的聚合函數和窗口函數去完成一些復雜的分析
*/