postgresql成本因子调整
????postgresql因子的調(diào)整主要有這四個(gè)cpu_tuple_cost,random_page_cost,cpu_index_tuple_cost,cpu_operator_cost。這四個(gè)因子的值影響著計(jì)劃中的cost值,這個(gè)因子大小的是否正確很大程度的影響著執(zhí)行計(jì)劃走的是否正確。
????1.安裝systemtap
????需要用到的工具是systemtap,在安裝systemtap前請(qǐng)先進(jìn)行如下操作
????
之后安裝相同版本號(hào)的kernel-devel,kernel-debuginfo,kernel-debuginfo-common(注意包括小版本號(hào)一定要相同)
????至于去哪找這些rpm包我是從這里找到的http://rpm.pbone.net/index.php3。如果實(shí)在找不到同版本的這3個(gè)安裝包建議換個(gè)版本的系統(tǒng)吧。之后安裝systemtap,
???
?如果安裝完后應(yīng)該是有這些包
??
????[root@bogon?~]#?stap?-ve?'probe?begin?{?log("hello?world")?exit()?}'測(cè)試下是否成功安裝
????
??
????systemtap安裝成功后開始安裝postgresql,我安裝的版本的9.3,源碼安裝的
????
????安裝步驟,就解壓后到目錄中執(zhí)行
????[postgres@bogon?postgresql-9.3.0]$?./configure?--prefix=/home/postgres/data?--enable-dtrace
??
??之后就是
????[postgres@bogon?postgresql-9.3.0]$?make?&&?make?install
????完成后運(yùn)行下
????[postgres@bogon?bin]$?pg_config?--configure
????
???
????接下來(lái)就是初始化數(shù)據(jù)庫(kù):initdb?-D?數(shù)據(jù)庫(kù)目錄。
????[postgres@bogon?data]$?pg_ctl?start?-D?pgdata?啟動(dòng)數(shù)據(jù)庫(kù)。
?
???3.調(diào)整因子前環(huán)境的配置
????創(chuàng)建測(cè)試用表:
????create?table?test(a?int,b?int);
????插入數(shù)據(jù):(需要數(shù)據(jù)有一定的離散性)
????insert?into?test?select?random()1000000,random()1000000?from?generate_series(1,1000000);
????創(chuàng)建索引:
????create?index?index_a?on?test(a);
????更新統(tǒng)計(jì)信息:
????analyse;
????將數(shù)據(jù)寫入磁盤:
????checkpoint;
????關(guān)閉數(shù)據(jù)庫(kù):
????pg_ctl?stop?-D?pgdata/
????清空操作系統(tǒng)緩存
????[root@bogon?~]#?sync;?echo?3?>?/proc/sys/vm/drop_caches
????下面就要使用stap了,具體代碼如下
????stap?-e?'
????global?a
????probe?process("/home/postgres/data/bin/postgres").mark("query__start")?{
????????delete?a
????????println("query__start?",?user_string($arg1),?"pid:",?pid())
????}
????probe?vfs.read.return?{
????????t?=?gettimeofday_ns()?-?@entry(gettimeofday_ns())
????????#?if?(execname()?==?"postgres"?&&?devname?!=?"N/A")
????????a[pid()]?<<<?t
????}
????probe?process("/home/postgres/data/bin/postgres").mark("query__done")?{
????????if?(@count(a[pid()]))?
????????printdln("**",?pid(),?@count(a[pid()]),?@avg(a[pid()]))
????????println("query__done?",?user_string($arg1),?"pid:",?pid())
????????if?(@count(a[pid()]))?{
????????println(@hist_log(a[pid()]))
????????#println(@hist_linear(a[pid()],1024,4096,100))
????}
??delete?a
}'?-x?2808
????這個(gè)a是一個(gè)數(shù)組中存著,pid號(hào),多少次讀取數(shù)據(jù)塊,讀取數(shù)據(jù)塊的平均時(shí)間,stap監(jiān)控著postgres這個(gè)進(jìn)程,vfs.read.return這個(gè)函數(shù)是得到塊設(shè)備讀入一個(gè)數(shù)據(jù)塊的時(shí)間,并存入數(shù)組a中,最后返回pid號(hào)和讀取塊的次數(shù)和平均讀取時(shí)間。-x?后面的數(shù)字要設(shè)置為你監(jiān)控的pid號(hào)
????postgres=#?select?pg_backend_pid();
????
????
????4.調(diào)整成本因子
????
????4.1調(diào)整全表掃描的相關(guān)因子
????首先得到會(huì)話的pid號(hào)之后運(yùn)行前面呢段代碼:
????
??
??確定模塊是否加載上了????[root@bogon?~]#?lsmod?|grep?stap
????
???
?執(zhí)行如下語(yǔ)句:????postgres=#?explain?(analyze,verbose,costs,buffers,timing)?select?*?from?test?;
????
????查看下stap的結(jié)果:
????
??
????
????
????補(bǔ)充一個(gè)圖還要查下pg_class中的relpages的數(shù)量,這個(gè)是整個(gè)表存儲(chǔ)的頁(yè)面數(shù)
????postgres=#?select?relpages?from?pg_class?where?relname='test';
????
???
????cost(真實(shí)執(zhí)行時(shí)間)=seqscan_costrelpages+cpu_tuple_costlines(表的行數(shù))
????根據(jù)上面的圖可以得到如下結(jié)果:
????cost=677.602
????seq_page_cost=148019*10^-6
????relpages=4425
????lines=1000000
????由這些值可得
????cpu_tuple_cost=0.000022617925
????seqscan_cost=0.148019
????這兩個(gè)值先記錄下來(lái)。
????我們可以set?seq_page_cost=0.148019;set?cpu_tuple_cost=0.000022617925;在進(jìn)行全表掃描看下結(jié)果。
????重復(fù)之前操作清理下系統(tǒng)緩存:
????[root@bogon?~]#?sync;?echo?3?>?/proc/sys/vm/drop_caches
????重啟數(shù)據(jù)庫(kù);
????設(shè)置這兩個(gè)因子
????重新查詢下之前的語(yǔ)句
????
???
????
????4.2調(diào)整索引相關(guān)的成本因子
????重復(fù)之前調(diào)全表掃描因子的步驟,這里不再贅述。
????首先設(shè)置cpu_tuple_cost=1,random_page_cost=1,cpu_index_tuple_cost=1,cpu_operator_cost=1。設(shè)置的原因之后在進(jìn)行解釋。
????
??
????執(zhí)行如下語(yǔ)句:explain?(analyze,verbose,costs,buffers,timing)?select?*?from?test?where?a>489963;
????
????
????stap結(jié)果:
????
????索引掃描的代價(jià)計(jì)算公式是:
????cost=random_page_costblocks+cpu_tuple_costline1+cpu_index_tuple_costline2+cpu_operator_costline2
????cost=9283.272
????random_page_cost=1.534983
????line1=508823
????line2=?
????blocks=?
????這個(gè)line2就和之前設(shè)置所有因子都是1就有關(guān)系了,我們可以通過(guò)調(diào)整cpu_operator_cost為2其他因子不變,兩個(gè)得到的cost結(jié)果相減就可以得到line2了,blocks也是同理通過(guò)調(diào)整random_page_cost來(lái)得到結(jié)果。
????
???
?line2=2041453-1532460=508993????
????
?
?blocks=1538282-1532460=5822
????2cpu_operator_cost=cpu_index_tuple_cost
????綜上可得出
????cpu_operator_cost=0.00548671355463809587
????cpu_index_tuple_cost=0.01097342710927619174
????random_page_cost=1.534983
????我們?cè)賮?lái)重新調(diào)整完因子后再測(cè)試下語(yǔ)句
????
???
????
????
????最終結(jié)果是
????cpu_operator_cost=0.00548671355463809587
????cpu_index_tuple_cost=0.01097342710927619174
????random_page_cost=1.534983
????cpu_tuple_cost=0.000022617925
????seqscan_cost=0.148019
總結(jié)
以上是生活随笔為你收集整理的postgresql成本因子调整的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 【Spark Summit East 2
- 下一篇: Flask-第二课:路由