postgres=# explain (analyze,verbose,costs,buffers,timing) select info from tbl where info ='girl'; QUERY PLAN ------------------------------------------------------------------------------------------------------------------- Seq Scan on public.tbl (cost=0.00..5456.48 rows=300016 width=4) (actual time=0.013..216.970 rows=299999 loops=1) Output: info Filter: (tbl.info = 'girl'::text) Rows Removed by Filter: 4999 Buffers: shared hit=1644 Planning Time: 0.067 ms Execution Time: 404.836 ms (7 rows)
postgres=# SET postgres=# set enable_seqscan=off; explain (analyze,verbose,costs,buffers,timing) select info from tbl where info ='girl'; QUERY PLAN --------------------------------------------------------------------------------------------------------------------------------------- Index Only Scan using tbl_ix on public.tbl (cost=0.30..6202.58 rows=300016 width=4) (actual time=0.025..196.965 rows=299999 loops=1) Output: info Index Cond: (tbl.info = 'girl'::text) Heap Fetches: 0 Buffers: shared hit=237 Planning Time: 0.067 ms Execution Time: 377.856 ms (7 rows)
發現明明查詢語法都一樣,只是透過 Setting 發現明明是 Index Only Scan 執行實際時間成本比較低,但 query optimizer 卻選擇 table scan,會造成上面問題是因為成本因子沒有調教所造成
codename=$(lsb_release -c | awk '{print $2}') sudotee /etc/apt/sources.list.d/ddebs.list << EOF deb http://ddebs.ubuntu.com/ ${codename} main restricted universe multiverse deb http://ddebs.ubuntu.com/ ${codename}-security main restricted universe multiverse deb http://ddebs.ubuntu.com/ ${codename}-updates main restricted universe multiverse deb http://ddebs.ubuntu.com/ ${codename}-proposed main restricted universe multiverse EOF sudo apt-get update sudo apt-get install systemtap -y sudo apt-get install gcc -y sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys C8CAB6595FDFF622 sudo apt-get install linux-image-$(uname -r)-dbgsym -y sudo apt-get install linux-headers-$(uname -r) -y
如果下載完畢會顯示下載完畢的資訊如下
1 2 3 4 5 6 7 8 9 10 11 12
root/pg_log# sudo apt-get install linux-image-$(uname -r)-dbgsym -y Reading package lists... Done Building dependency tree Reading state information... Done linux-image-5.4.0-1045-aws-dbgsym is already the newest version (5.4.0-1045.47). 0 upgraded, 0 newly installed, 0 to remove and 64 not upgraded. root/pg_log# sudo apt-get install linux-headers-$(uname -r) -y Reading package lists... Done Building dependency tree Reading state information... Done linux-headers-5.4.0-1045-aws is already the newest version (5.4.0-1045.47). 0 upgraded, 0 newly installed, 0 to remove and 64 not upgraded.
安裝完後使用 stap 應該可以看到類似下面提示
1 2 3 4
root:/pg_log# stap A script must be specified. Try '-i'for building a script interactively. Try '--help'for more information.
postgres=# set random_page_cost=1; SET postgres=# set cpu_tuple_cost=1; SET postgres=# set cpu_index_tuple_cost=1; SET postgres=# set cpu_operator_cost=1; SET postgres=# postgres=# set enable_seqscan=off; set enable_bitmapscan=off; explain (analyze,verbose,costs,buffers,timing) select*from tbl where id >1998760000; SET SET QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------- Index Scan using ix_tbl on public.tbl (cost=174.00..34131.99rows=8539 width=49) (actual time=1.305..3948.019rows=9406 loops=1) Output: id, val, info, create_time Index Cond: (tbl.id >1998760000) Buffers: shared hit=286 read=9161 Query Identifier: -1014555039272331675 Planning: Buffers: shared hit=69 read=28 Planning Time: 13.757 ms Execution Time: 3961.950 ms (9rows)
postgres=# set random_page_cost=2; SET postgres=# set cpu_tuple_cost=1; SET postgres=# set cpu_index_tuple_cost=1; SET postgres=# set cpu_operator_cost=1; SET postgres=# postgres=# set enable_seqscan=off; set enable_bitmapscan=off; explain (analyze,verbose,costs,buffers,timing) select * from tbl whereid > 1998760000; SET SET QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------- Index Scan using ix_tbl on public.tbl (cost=174.00..42472.99 rows=8539 width=49) (actual time=1.447..3887.553 rows=9406 loops=1) Output: id, val, info, create_time Index Cond: (tbl.id > 1998760000) Buffers: shared hit=286 read=9161 Query Identifier: -1014555039272331675 Planning: Buffers: shared hit=72 read=28 Planning Time: 15.066 ms Execution Time: 3898.528 ms (9 rows)
postgres=# set random_page_cost=1; SET postgres=# set cpu_tuple_cost=1; SET postgres=# set cpu_index_tuple_cost=1; SET postgres=# set cpu_operator_cost=2; SET postgres=# postgres=# set enable_seqscan=off; set enable_bitmapscan=off; explain (analyze,verbose,costs,buffers,timing) select*from tbl where id >1998760000; SET SET QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------- Index Scan using ix_tbl on public.tbl (cost=348.00..42844.99rows=8539 width=49) (actual time=1.158..3981.194rows=9406 loops=1) Output: id, val, info, create_time Index Cond: (tbl.id >1998760000) Buffers: shared hit=286 read=9161 Query Identifier: -1014555039272331675 Planning: Buffers: shared hit=72 read=28 Planning Time: 15.108 ms Execution Time: 3992.758 ms (9rows)
計算步驟跟上面差不多,我就直接帶到核心計算公式
1 2
42844.99 - 34131.99 = x x = 8713
自此我們就把所有資訊都取得了
調教最終數值
最終執行時間成本 = 3948.019
cpu_tuple_cost = 0.0008649005546666667
tuple search row = 9406
執行平均 IO 420006 ns = 0.420006 ms (random_page_cost)
--index scan test set cpu_index_tuple_cost =0.016272126542292986; set cpu_operator_cost=0.03254425308458597; set cpu_tuple_cost =0.0008649005546666667; set seq_page_cost =0.006662; set random_page_cost =0.420006;
set enable_seqscan=off; set enable_bitmapscan=off; explain (analyze,verbose,costs,buffers,timing) select*from tbl where id >1998760000;
--table scan tests set cpu_index_tuple_cost =0.016272126542292986; set cpu_operator_cost=0.03254425308458597; set cpu_tuple_cost =0.0008649005546666667; set seq_page_cost =0.006662; set random_page_cost =0.420006;
postgres=# set enable_seqscan=off; set enable_bitmapscan=off; explain (analyze,verbose,costs,buffers,timing) select*from tbl where id >1998760000; SET SET QUERY PLAN -------------------------------------------------------------------------------------------------------------------------------- Index Scan using ix_tbl on public.tbl (cost=0.43..3575.13rows=8539 width=49) (actual time=1.402..3933.451rows=9406 loops=1) Output: id, val, info, create_time Index Cond: (tbl.id >1998760000) Buffers: shared hit=286 read=9161 Query Identifier: -1014555039272331675 Planning: Buffers: shared hit=72 read=28 Planning Time: 14.948 ms Execution Time: 3944.197 ms (9rows)
postgres=# set cpu_operator_cost=0.03254425308458597; SET postgres=# set cpu_tuple_cost =0.0008649005546666667; SET postgres=# set seq_page_cost =0.006662; SET postgres=# set random_page_cost =0.420006; SET postgres=# postgres=# set enable_seqscan=off; set enable_bitmapscan=off; explain (analyze,verbose,costs,buffers,timing) select*from tbl where id >1998760000; SET SET QUERY PLAN -------------------------------------------------------------------------------------------------------------------------------- Index Scan using ix_tbl on public.tbl (cost=5.66..3933.16rows=8539 width=49) (actual time=1.092..3360.230rows=9406 loops=1) Output: id, val, info, create_time Index Cond: (tbl.id >1998760000) Buffers: shared hit=286 read=9161 Query Identifier: -1014555039272331675 Planning: Buffers: shared hit=72 read=28 Planning Time: 15.869 ms Execution Time: 3369.814 ms (9rows)