第一部分:字符集規(guī)范
【強(qiáng)制】數(shù)據(jù)庫(kù)字符集指定utf-8姨拥,并且只支持utf-8绅喉。
命令規(guī)范
- 【建議】庫(kù)名統(tǒng)一使用小寫方式,中間用下劃線(_)分割叫乌,長(zhǎng)度62字節(jié)內(nèi)
- 【建議】表名稱大小寫敏感柴罐,統(tǒng)一使用小寫方式,中間用下劃線(_)分割憨奸,長(zhǎng)度64字節(jié)內(nèi)
第二部分:建表規(guī)范
- 【強(qiáng)制】確保每個(gè)tablet大小為1-3G之間革屠。舉例:假設(shè)表內(nèi)單分區(qū)數(shù)據(jù)量在100G,按天分區(qū),bucket數(shù)量100個(gè)排宰。
- 【強(qiáng)烈建議】不要使用Auto Bucket 似芝,按照自己的數(shù)據(jù)量來(lái)進(jìn)行分區(qū)分桶,這樣你的導(dǎo)入及查詢性能都會(huì)得到很好的效果板甘,Auto Bucket 會(huì)造成 tablet 數(shù)量過(guò)多党瓮,造成大量小文件的問(wèn)題。
- 【強(qiáng)制】 5 億以上的數(shù)據(jù)必須設(shè)置分區(qū)分桶策略
- 維度表:緩慢增長(zhǎng)的盐类,可以使用單分區(qū)寞奸,在分桶策略上使用常用查詢條件(這個(gè)字段數(shù)據(jù)分步相對(duì)均衡)分桶,
- 100M以內(nèi):1 buckets
- 100M-1G :3-5 個(gè) Buckets
- 大于1G-3G : 5-7個(gè) buckets
- 3-5G : 7-10 個(gè) buckets
- 事實(shí)表
- 沒(méi)有辦法分區(qū)的在跳,數(shù)據(jù)又緩慢增長(zhǎng)的:?jiǎn)蝹€(gè)tablet數(shù)據(jù)量保持在1-3G枪萄;比如5億數(shù)據(jù)大小在20G,bucket數(shù)量給20個(gè)
- 沒(méi)有辦法分區(qū)的猫妙,數(shù)據(jù)又較快增長(zhǎng)的瓷翻,沒(méi)辦法按照時(shí)間動(dòng)態(tài)分區(qū),可以適當(dāng)放大一下你的bucket數(shù)量吐咳,按照你的數(shù)據(jù)保存周期(180天)數(shù)據(jù)總量逻悠,來(lái)估算你的bucket數(shù)量應(yīng)該是多少,建議還是單個(gè)bucket大小在1-3G韭脊。
- 避免數(shù)據(jù)傾斜的問(wèn)題
- 一個(gè)是對(duì)分桶字段進(jìn)行加鹽處理,業(yè)務(wù)上查詢的時(shí)候也是要同樣的加鹽策略单旁,這樣能利用到分桶數(shù)據(jù)剪裁能力
- 另外一個(gè)是數(shù)據(jù)隨機(jī)分桶沪羔,這種缺點(diǎn)是沒(méi)辦法利用數(shù)據(jù)分桶剪裁能力,數(shù)據(jù)分布會(huì)很均勻
- 避免數(shù)據(jù)傾斜的問(wèn)題
- 維度表:緩慢增長(zhǎng)的盐类,可以使用單分區(qū)寞奸,在分桶策略上使用常用查詢條件(這個(gè)字段數(shù)據(jù)分步相對(duì)均衡)分桶,
- 【建議】 1000w-2 億以內(nèi)數(shù)據(jù)為了方便可以不設(shè)置分區(qū),直接用分桶策略蔫饰。(不設(shè)置其實(shí)Doris內(nèi)部會(huì)有個(gè)默認(rèn)分區(qū))
- 參考上面第二點(diǎn)
- 【強(qiáng)制】 2000kw 以內(nèi)數(shù)據(jù)禁止使用動(dòng)態(tài)分區(qū)(動(dòng)態(tài)分區(qū)會(huì)自動(dòng)創(chuàng)建分區(qū)琅豆,而小表用戶客戶關(guān)注不到,會(huì)創(chuàng)建出大量不使用分區(qū)分桶)
- 參考上面第二點(diǎn)
- 【強(qiáng)制】對(duì)于有大量歷史分區(qū)數(shù)據(jù)篓吁,但是歷史數(shù)據(jù)比較少茫因,或者不均衡,或者查詢概率的情況杖剪,使用如下方式將數(shù)據(jù)放在特殊分區(qū)冻押。
- 對(duì)于歷史數(shù)據(jù),如果數(shù)據(jù)量比較小我們可以創(chuàng)建歷史分區(qū)(比如年分區(qū)盛嘿,月分區(qū))洛巢,將所有歷史數(shù)據(jù)放到對(duì)應(yīng)分區(qū)里
- 創(chuàng)建歷史分區(qū)方式
FROM ("2000-01-01") TO ("2022-01-01") INTERVAL 1 YEAR
(
PARTITION p00010101_1899 VALUES [('0001-01-01'), ('1900-01-01')),
PARTITION p19000101 VALUES [('1900-01-01'), ('1900-01-02')),
...
PARTITION p19000104_1999 VALUES [('1900-01-04'), ('2000-01-01')),
FROM ("2000-01-01") TO ("2022-01-01") INTERVAL 1 YEAR,
PARTITION p30001231 VALUES [('3000-12-31'), ('3001-01-01')),
PARTITION p99991231 VALUES [('9999-12-31'), (MAXVALUE))
)
-
【強(qiáng)制】如果分桶字段存在30%以上的數(shù)據(jù)傾斜,則禁止使用Hash分桶策略次兆,改使用random分桶策略
- 參考上面第二點(diǎn)事實(shí)表部分
-
【建議】前綴索引的第一個(gè)字段一定是最長(zhǎng)查詢的字段稿茉,并且需要是高基字段。這里面選取分區(qū)分桶外最長(zhǎng)查詢且高基數(shù)的列
- 前綴索引(36位):第一個(gè)字段查詢性能最好芥炭,前綴索引碰見varchar類型的字段漓库,會(huì)自動(dòng)截?cái)嗲?0個(gè)字符
- Int(4)+ Int(4) + varchar(50),前綴索引長(zhǎng)度只有28
- Int(4) + varchar(50) + Int(4)园蝠,前綴索引長(zhǎng)度只有24
- varchar(10) + varchar(50) 米苹,前綴索引長(zhǎng)度只有30
- 最常用的查詢字段如果能放到前綴索引里盡可能放到前前綴索引里,如果不能砰琢,可以放到分桶字段里
- 分桶字段注意事項(xiàng):這個(gè)一般是數(shù)據(jù)分布比較均衡的蘸嘶,也是經(jīng)常使用的字段,最好是高基數(shù)字段
- 前綴索引(36位):第一個(gè)字段查詢性能最好芥炭,前綴索引碰見varchar類型的字段漓库,會(huì)自動(dòng)截?cái)嗲?0個(gè)字符
good case :UNIQUE KEY(
user_id
,age
) user_id最長(zhǎng)被查詢陪汽,且數(shù)據(jù)分布比較散bad case :UNIQUE KEY(
age
,user_id
) age是低基數(shù)列训唱,且可能存在數(shù)據(jù)傾斜【強(qiáng)制】表的副本數(shù)必須為3
【建議】前綴索引中的字段長(zhǎng)度盡可能明確,因?yàn)镈oris只有前36個(gè)字節(jié)能走前綴索引
-
【強(qiáng)制】除了UNIQUE KEY和aggregate key要構(gòu)建key的情況挚冤,否則不要基數(shù)(例如user_type)小于50的字段建立任何索引况增。因?yàn)镈oris內(nèi)置了字典類型優(yōu)化。
- 已經(jīng)有了低基數(shù)優(yōu)化了
- Unique Key 是aggregate key 的一個(gè)特例训挡,當(dāng)aggregate key 的key 保持唯一其實(shí)就是Unqiue key 模型
-
【強(qiáng)制】BloomFilter索引必須在查詢條件是in或者=澳骤,并且是高基(5000以上)列上構(gòu)建。
- 數(shù)據(jù)基數(shù)在一半左右
- 類似身份證號(hào)這種基數(shù)特別高并且查詢是等值(=)查詢澜薄,使用Bitmap索引能極大加速
- Bloomfilter 使用場(chǎng)景:
- 首先BloomFilter適用于非前綴過(guò)濾为肮。
- 查詢會(huì)根據(jù)該列高頻過(guò)濾,而且查詢條件大多是 in 和 = 過(guò)濾肤京。
- 不同于Bitmap, BloomFilter適用于高基數(shù)列颊艳。比如UserID。因?yàn)槿绻麆?chuàng)建在低基數(shù)的列上,比如 “性別” 列棋枕,則每個(gè)Block幾乎都會(huì)包含所有取值白修,導(dǎo)致BloomFilter索引失去意義。
-
【強(qiáng)制】bitmap索引必須在一定基數(shù)范圍內(nèi)構(gòu)建重斑,太高或者太低的基數(shù)都不合適
- 這種索引更多的適合正交查詢
- 適用場(chǎng)景:
- 適用于低基數(shù)的列上兵睛,建議在100到100,000之間,如:職業(yè)窥浪、地市等祖很。 重復(fù)度過(guò)高則對(duì)比其他類型索引沒(méi)有明顯優(yōu)勢(shì);重復(fù)度過(guò)低寒矿,則空間效率和性能會(huì)大大降低突琳。 特定類型的查詢例如count、or符相、and 等邏輯操作因?yàn)橹恍枰M(jìn)行位運(yùn)算
- Bitmap 索引支持類型:
- bitmap 索引支持的數(shù)據(jù)類型如下:
TINYINT
SMALLINT
INT
BIGINT
CHAR
VARCHAR
DATE
DATETIME
LARGEINT
DECIMAL
BOOL
- bitmap 索引支持的數(shù)據(jù)類型如下:
【強(qiáng)制】?jī)|級(jí)別以上數(shù)據(jù)拆融,如果有模糊匹配,使用倒排索引或者是 NGram Bloomfilter
【建議】如果某個(gè)范圍數(shù)據(jù)在分區(qū)分桶和前綴索引中都不好設(shè)計(jì)啊终,可以考慮引入倒排索引加速镜豹。
-
【強(qiáng)制】單表物化視圖不能超過(guò)6個(gè)
- 單筆物化視圖是實(shí)時(shí)構(gòu)建
- 在unique 模型上物化視圖只能起到 Key 重新排序的作用,不能做數(shù)據(jù)的聚合蓝牲,因?yàn)閁nqiue模型的聚合模型是replace
【建議】建議使用JSON數(shù)據(jù)類型代替字符串類型存放JSON數(shù)據(jù)的使用方式
第三部分:數(shù)據(jù)變更規(guī)范
-
【強(qiáng)制】應(yīng)用程序不可以直接使用delete后者update語(yǔ)句變更數(shù)據(jù)趟脂,使用CDC的upsert方式來(lái)實(shí)現(xiàn)。
- 低頻操作上使用例衍,比如 Update 幾分鐘更新一次
- 如果使用 Delete 一定帶上分區(qū)條件
【強(qiáng)制】DBA執(zhí)行delete后者update語(yǔ)句時(shí)必須帶分區(qū)條件
【強(qiáng)制】禁止使用INSERT INTO tbl1 VALUES ("1"), ("a");這種方式寫入數(shù)據(jù)昔期。
-
【建議】特殊大的ETL操作,簡(jiǎn)單單獨(dú)在Session中設(shè)置超時(shí)時(shí)間
-
SELECT
/*+ SET_VAR(query_timeout = 1*/ sleep(3);
類似這樣通過(guò)Hint方式去設(shè)置Session 會(huì)話變量佛玄,不要設(shè)置全局的系統(tǒng)變量
-
第四部分:數(shù)據(jù)查詢規(guī)范
【強(qiáng)制】in 中條件超過(guò) 2000 后硼一,必須修改為子查詢
【強(qiáng)制】禁止使用REST API(Statement Execution Action)執(zhí)行大量SQL查詢,改接口僅僅用于集群維護(hù)梦抢。
-
【建議】一次insert into select 數(shù)據(jù)超過(guò)1億條后般贼,建議拆分為多個(gè)insert into select語(yǔ)句執(zhí)行,分成多個(gè)批次來(lái)執(zhí)行奥吩。
-
如果真的是要這樣執(zhí)行哼蛆,在集群資源相對(duì)空閑的時(shí)候可以通過(guò)調(diào)整并發(fā)度來(lái)加快的數(shù)據(jù)導(dǎo)入速度
2.0 以后版開啟了Pipeline 就不需要設(shè)置并發(fā)度了
set parallel_fragment_exec_instance_num = 8 或者 16 建議是你CPU內(nèi)核的一半 insert into new_tbl select * from old_tbl
-
-
【強(qiáng)制】query查詢條件返回結(jié)果在5w條以上,使用JDBC Catalog或者OUTFILE方式導(dǎo)出霞赫。不然大量FE上數(shù)據(jù)傳輸將占用FE資源腮介,影響集群穩(wěn)定性
- 如果你是交互式查詢,建議使用分頁(yè)方式(offset limit)绩脆,分頁(yè)要加Order by
- 如果是數(shù)據(jù)導(dǎo)出提供給第三方使用萤厅,建議使用 outfile 或者 export 方式
-
【建議】query查詢?nèi)绻写罅康臄?shù)據(jù)傳輸需求橄抹,建議部署observer節(jié)點(diǎn)并在該該節(jié)點(diǎn)執(zhí)行查詢(私有化部署)
- 建議的方式是 1 FE(Follower) + 多個(gè) OBserver(FE)方式靴迫,讀寫分析惕味,所有的寫連接 Follower,所有的讀連接Observer
【建議】盡量不要使用OR 作為 JOIN條件
【建議】大量數(shù)據(jù)排序(5億以上)后返回部分?jǐn)?shù)據(jù)玉锌,建議先減少數(shù)據(jù)范圍在執(zhí)行排序名挥,否則大量排序會(huì)影響性能。
select * from kunpeng_risk_record krr where krr.event_occur_time_date between '2023-10-01 00:00:00' and '2023-10-25 23:59:59' and krr.partner_code = 'liveme' order by krr.sequence_id desc limit 20;
例如將
from table order by datatime desc limit 10 優(yōu)化為from table where datatime='2023-10-20' order by datatime desc limit 10
-
【強(qiáng)制】2個(gè)以上大于3億的表 JOIN 使用 Colocate JOIN
- Colocate Join 的使用參照:Colocation Join - Apache Doris
-
【強(qiáng)制】?jī)|級(jí)別大表禁止使用select * 查詢主守,查詢時(shí)需要明確要查詢的字段
SQL Block方式禁止這種操作
如果是高并發(fā)點(diǎn)查禀倔,建議開啟行存
表屬性級(jí)別
"enable_unique_key_merge_on_write" = "true", "store_row_column" = "true" be.conf disable_storage_row_cache 是否開啟行緩存, 默認(rèn)不開啟
- 使用PrepareStatement模板
【強(qiáng)制】?jī)|級(jí)以上表數(shù)據(jù)查詢必須帶分區(qū)分桶條件