這篇文章主要講解了“怎么理解PostgreSQL全表掃描問題”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“怎么理解PostgreSQL全表掃描問題”吧!
10多年的廣宗網(wǎng)站建設經(jīng)驗,針對設計、前端、開發(fā)、售后、文案、推廣等六對一服務,響應快,48小時及時工作處理。營銷型網(wǎng)站的優(yōu)勢是能夠根據(jù)用戶設備顯示端的尺寸不同,自動調整廣宗建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調整網(wǎng)站的寬度,無論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設計,從而大程度地提升瀏覽體驗。創(chuàng)新互聯(lián)建站從事“廣宗網(wǎng)站設計”,“廣宗網(wǎng)站推廣”以來,每個客戶項目都認真落實執(zhí)行。本節(jié)內容來源于PGer的一個問題:
Q:
由于多版本的存在,那么全表掃描是不是需要更長的時間了呢?
A:
關于全表掃描,不妨考慮2種極端的情況:
1.insert數(shù)據(jù)(事務已提交,下同),沒有執(zhí)行update/delete,沒有dead tuple,全表掃描效率沒有影響;
2.insert數(shù)據(jù),執(zhí)行了大量的update/delete,同時禁用了autovacuum也沒有手工執(zhí)行vacuum,那么存在大量的dead tuple,性能上一是需要更多的IO操作,二是需要執(zhí)行額外的CPU判斷(對于所有的tuple都要執(zhí)行可見性判斷).
其判斷邏輯如下:
((Xmin == my-transaction && inserted by the current transaction Cmin < my-command && before this command, and (Xmax is null || the row has not been deleted, or (Xmax == my-transaction && it was deleted by the current transaction Cmax >= my-command))) but not before this command, || or (Xmin is committed && the row was inserted by a committed transaction, and (Xmax is null || the row has not been deleted, or (Xmax == my-transaction && the row is being deleted by this transaction Cmax >= my-command) || but it’s not deleted "yet", or (Xmax != my-transaction && the row was deleted by another transaction Xmax is not committed)))) that has not been committed
簡單做個實驗,創(chuàng)建一張表t_fts,
1.插入數(shù)據(jù),大小為s1,執(zhí)行全表掃描,時間為m秒;
2.update所有行,大小為s2,執(zhí)行全表掃描,時間為n秒.
理論上來說,n應為m的s2/s1倍左右(相對于IO時間,如果tuple數(shù)不多,CPU時間可以忽略不計).
創(chuàng)建數(shù)據(jù)表,插入數(shù)據(jù):
testdb=# drop table if exists t_fts; DROP TABLE testdb=# create table t_fts(id int,c1 varchar(200),c2 varchar(200)); CREATE TABLE testdb=# testdb=# insert into t_fts select x,lpad('c1'||x,200,'x'),lpad('c1'||x,200,'x') from generate_series(1,2000000) as x; INSERT 0 2000000 testdb=# select pg_size_pretty(pg_table_size('t_fts')); pg_size_pretty ---------------- 868 MB (1 row)
禁用autovacuum,執(zhí)行查詢:
testdb=# alter system set autovacuum=off; ALTER SYSTEM testdb=# show autovacuum; autovacuum ------------ off (1 row) testdb=# explain analyze verbose select * from t_fts; QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------- Seq Scan on public.t_fts (cost=0.00..131112.16 rows=2000016 width=412) (actual time=0.048..1086.289 rows=2000000 loops=1) Output: id, c1, c2 Planning Time: 30.762 ms Execution Time: 1181.360 ms (4 rows)
執(zhí)行update:
testdb=# update t_fts set c1 = lpad('c1'||(id+1),200,id+1||''),c2 = lpad('c1'||(id+1),200,id+1||''); UPDATE 2000000 testdb=# select pg_size_pretty(pg_table_size('t_fts')); pg_size_pretty ---------------- 1737 MB (1 row) testdb=# explain analyze verbose select * from t_fts; QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------- -- Seq Scan on public.t_fts (cost=0.00..262223.14 rows=4000014 width=412) (actual time=3168.414..6117.780 rows=2000000 loops=1 ) Output: id, c1, c2 Planning Time: 5.493 ms Execution Time: 6205.705 ms (4 rows) testdb=# explain analyze verbose select * from t_fts; QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------- - Seq Scan on public.t_fts (cost=0.00..262223.14 rows=4000014 width=412) (actual time=776.660..2311.270 rows=2000000 loops=1) Output: id, c1, c2 Planning Time: 0.426 ms Execution Time: 2391.895 ms (4 rows) testdb=# explain analyze verbose select * from t_fts; QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------- - Seq Scan on public.t_fts (cost=0.00..262223.14 rows=4000014 width=412) (actual time=728.758..2293.157 rows=2000000 loops=1) Output: id, c1, c2 Planning Time: 0.481 ms Execution Time: 2373.241 ms (4 rows)
感謝各位的閱讀,以上就是“怎么理解PostgreSQL全表掃描問題”的內容了,經(jīng)過本文的學習后,相信大家對怎么理解PostgreSQL全表掃描問題這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關知識點的文章,歡迎關注!