GreenPlum之日常SQL腳本筆記(二)

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自身提供的聚合函數和窗口函數去完成一些複雜的分析
*/









發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章