-
建議對DB object尤其是COLUMN加COMMENT,便于后續了解業務及維護注釋前后的數據表可讀性對比,有注釋的一看就明白。
teledb=# \d+ t_oids; Table "public.t_oids" Column | Type | Collation | Nullable | Default | Storage | Stats target | Descripti on --------+--------------------------------+-----------+----------+---------+----------+--------------+---------- --- id | integer | | not null | | plain | | name | character varying | | | | extended | | birth | timestamp(0) without time zone | | | | plain | | city | character varying | | | | extended | | Indexes: "t_oids_pkey" PRIMARY KEY, btree (id) Has OIDs: yes Distribute By: SHARD(id) Location Nodes: ALL DATANODES ^ teledb=# comment on column t_oids.name is '姓名'; COMMENT teledb=# comment on column t_oids.city is '居住城市'; COMMENT teledb=# \d+ t_oids; Table "public.t_oids" Column | Type | Collation | Nullable | Default | Storage | Stats target | Descripti on --------+--------------------------------+-----------+----------+---------+----------+--------------+---------- --- id | integer | | not null | | plain | | name | character varying | | | | extended | | 姓名 birth | timestamp(0) without time zone | | | | plain | | city | character varying | | | | extended | | 居住城市 Indexes: "t_oids_pkey" PRIMARY KEY, btree (id) Has OIDs: yes Distribute By: SHARD(id) Location Nodes: ALL DATANODES -
建議非必須時避免select *,只取所需字段,以減少包括不限于網絡帶寬消耗。
teledb=# explain select * from t_oids; QUERY PLAN ---------------------------------------------------------------- Remote Fast Query Execution (cost=0.00..0.00 rows=0 width=0) Node/s: dn01, dn02 -> Seq Scan on t_oids (cost=0.00..16.30 rows=630 width=76) (3 rows) teledb=# explain select id from t_oids; QUERY PLAN --------------------------------------------------------------- Remote Fast Query Execution (cost=0.00..0.00 rows=0 width=0) Node/s: dn01, dn02 -> Seq Scan on t_oids (cost=0.00..16.30 rows=630 width=4) (3 rows) -
建議update時盡量做<>判斷,如update table_a set column_b = c where column_b <> c;
teledb=# update t_oids set city = '測試'; UPDATE 4 teledb=# select xmin,* from t_oids; xmin | id | name | birth | city ------+----+------+---------------------+------ 1181 | 1 | 張三 | 2000-12-01 00:00:00 | 測試 1147 | 3 | 王五 | 2004-09-01 00:00:00 | 測試 1147 | 4 | 陳六 | 2022-01-01 00:00:00 | 測試 1181 | 2 | 李四 | 1997-03-24 00:00:00 | 測試 (4 rows) teledb=# update t_oids set city = '測試'; UPDATE 4 teledb=# select xmin,* from t_oids; xmin | id | name | birth | city ------+----+------+---------------------+------ 1182 | 1 | 張三 | 2000-12-01 00:00:00 | 測試 1182 | 2 | 李四 | 1997-03-24 00:00:00 | 測試 1148 | 3 | 王五 | 2004-09-01 00:00:00 | 測試 1148 | 4 | 陳六 | 2022-01-01 00:00:00 | 測試 (4 rows) teledb=# update t_oids set city = '測試' where city != '測試'; UPDATE 0 teledb=# select xmin,* from t_oids; xmin | id | name | birth | city ------+----+------+---------------------+------ 1182 | 1 | 張三 | 2000-12-01 00:00:00 | 測試 1182 | 2 | 李四 | 1997-03-24 00:00:00 | 測試 1148 | 3 | 王五 | 2004-09-01 00:00:00 | 測試 1148 | 4 | 陳六 | 2022-01-01 00:00:00 | 測試上面的效果是一樣的,但帶條件的更新不會產生一個新的版本記錄,不需要系統執行vacuum 回收垃圾數據。
-
建議將單個事務的多條SQL操作,分解、拆分,或者不放在一個事務里,讓每個事務的粒度盡可能小,盡量lock少的資源,避免lock 、dead lock的產生。
會話1 把所有數據都更新但不提交,鎖住了所有數據
teledb=# begin; BEGIN teledb=# update t_oids set city = 'city'; UPDATE 4會話2 等待
teledb=# update t_oids set city = 'session2';會話3 等待
teledb=# update t_oids set city = 'session3';如果會話1分批更新的話,則會話2和會話3中就能部分提前完成,這樣可以避免大量的鎖等待和出現大量的session占用系統資源,在做全表更新時請使用這種方法來執行。
-
建議大批量的數據入庫時,使用copy,不建議使用insert,以提高寫入速度。
-
建議對報表類的或生成基礎數據的查詢,使用物化視圖(MATERIALIZED VIEW)定期固化數據快照,避免對多表(尤其是讀寫頻繁的表)重復跑相同的查詢,且物化視圖支持REFRESH MATERIALIZED VIEW CONCURRENTLY,支持并發更新。
teledb=# select count(1) from teledb_pg1; count --------- 1000000 (1 row) Time: 57.713 ms teledb=# create materialized view count_view as select count(1) as num from teledb_pg1; SELECT 1 Time: 107.264 ms teledb=# select num from count_view; num --------- 1000000 (1 row) Time: 0.548 ms性能提高上百倍。
有數據變化時刷新方法。
teledb=# insert into teledb_pg1 select t,md5(random()::text) from generate_series(1,1000000) as t; INSERT 0 1000000 Time: 2817.703 ms (00:02.818) teledb=# select count(1) from teledb_pg1; count --------- 2000000 (1 row) Time: 147.231 ms teledb=# refresh materialized view count_view; REFRESH MATERIALIZED VIEW Time: 259.462 ms teledb=# select num from count_view; num --------- 2000000 (1 row) Time: 0.555 ms -
建議復雜的統計查詢可以嘗試窗口函數。
-
兩表join時盡量的使用分布key進行join。
-
分布鍵用唯一索引代替主鍵
teledb=# create unique index t_oid_id_uidx on t_oids using btree(id); CREATE INDEX因為唯一索引后期的維護成本比主鍵要低很多。
-
分布鍵無法建立唯一索引則要建立普通索引,提高查詢的效率
teledb=# create index t_oids_name_idx on t_oids using btree(name); CREATE INDEX這樣兩表在join查詢時返回少量數據時的效率才會高。
-
不要對字段建立外鍵
說明目前TeleDB還不支持多 DN 外鍵約束。?
開發相關規范
更新時間 2025-02-05 09:36:45
最近更新時間: 2025-02-05 09:36:45
分享文章
本頁介紹天翼云TeleDB數據庫開發相關的規范。