分表和索引并不是二選一的問題
通常使用MySQL時(shí)(其余的數(shù)據(jù)庫(kù)也一樣),大多數(shù)時(shí)候索引是必須要增加的,好處是查詢速度提升非常大,數(shù)據(jù)量越多越明顯;缺點(diǎn)是會(huì)對(duì)新增、修改、刪除的速度造成一定程度的影響,不過這個(gè)影響和查詢效率的提升相比,不值一提。
當(dāng)單表中的數(shù)據(jù)量進(jìn)一步增多,例如到了大幾千萬、幾億這個(gè)級(jí)別,單臺(tái)MySQL已經(jīng)不足以支撐這么多的數(shù)據(jù)了,這時(shí)候就要考慮分區(qū)、分表或分庫(kù)了;當(dāng)然分表之后,每一個(gè)子表中仍然可以有索引。
如果非要說分表查詢和索引查詢哪個(gè)快,當(dāng)數(shù)據(jù)量沒達(dá)到需要分表的程度時(shí),比如只有一百萬的數(shù)據(jù)量,我覺得還是索引查詢快,畢竟分表查詢還需要程序路由到數(shù)據(jù)所在的分區(qū)上,這個(gè)也是需要消耗時(shí)間的。
多說說分表的事兒MySQL單表數(shù)據(jù)量在一千萬以內(nèi)的時(shí)候,性能是比較好的,超過千萬性能會(huì)有下降,到了五六千萬以上,性能下降就比較明顯了,這是就要考慮分表了。
分表另外一個(gè)好處是,單個(gè)服務(wù)器的性能畢竟是有限的,例如磁盤的IO,分表后將子表部署在不同的磁盤上(也可以直接分庫(kù)),可以利用多臺(tái)服務(wù)器的資源,更好地支持高并發(fā)。
常見的分庫(kù)分表策略RANGE分區(qū):根據(jù)某一個(gè)字段的區(qū)間,進(jìn)行分區(qū)。比如按照id分區(qū),1到10萬一個(gè)分區(qū),10萬零1到20萬一個(gè)分區(qū)。
HASH分區(qū):定義一個(gè)表達(dá)式,對(duì)表達(dá)式的結(jié)果進(jìn)行分區(qū)選擇。例如把id和某個(gè)整數(shù)進(jìn)行取模運(yùn)算,結(jié)果為1的是一個(gè)分區(qū),結(jié)果是2的一個(gè)分區(qū)。
業(yè)務(wù)字段分區(qū):這個(gè)就容易理解了,在業(yè)務(wù)數(shù)據(jù)中選擇一個(gè)合適的字段,作為分區(qū)字段。比如按照公司碼分區(qū),companyCode=1(北京)為一個(gè)分區(qū),companyCode=2(天津)為一個(gè)分區(qū);當(dāng)然,一般不會(huì)選擇companyName=北京/天津這樣的字段;不過這種分表策略,不能保證數(shù)據(jù)平均,比如北京有五千萬數(shù)據(jù),天津有五百萬數(shù)據(jù)。
分表/分庫(kù)雖然看起來很美好,但是問題也不少:跨庫(kù)關(guān)聯(lián)、分布式事務(wù)、結(jié)果集合并/排序等問題,都是需要考慮解決的。
我將持續(xù)分享Java開發(fā)、架構(gòu)設(shè)計(jì)、程序員職業(yè)發(fā)展等方面的見解,希望能得到你的關(guān)注。