1.首先舅世,讓我們先熟悉一下sql的執(zhí)行過(guò)程旦委,當(dāng)你在sql客戶(hù)端(如命令行或者navicat)提交一條sql后,sql解析引擎會(huì)被啟動(dòng)雏亚,此時(shí)缨硝,sql引擎會(huì)去解析優(yōu)化這條sql,比如:有的時(shí)候你發(fā)現(xiàn)你寫(xiě)的sql查詢(xún)條件中的數(shù)據(jù)類(lèi)型雖然和數(shù)據(jù)庫(kù)表定義的數(shù)據(jù)類(lèi)型不一致罢低,但是還是能夠得到正確的執(zhí)行查辩,是因?yàn)閿?shù)據(jù)庫(kù)引擎幫你做了自動(dòng)轉(zhuǎn)化,不僅如此网持,數(shù)據(jù)庫(kù)表定義了多個(gè)索引宜岛,你寫(xiě)的sql引擎會(huì)幫你選擇最優(yōu)的一個(gè),這些都是在此階段完成的功舀。接下來(lái)萍倡,數(shù)據(jù)庫(kù)引擎會(huì)拿著優(yōu)化好的sql命令語(yǔ)義去硬盤(pán)中查找數(shù)據(jù),然后將查找到的數(shù)據(jù)返回辟汰。
(1)索引遣铝,建立索引是數(shù)據(jù)庫(kù)各種優(yōu)化方案之中成本最低佑刷,見(jiàn)效最快的解決方案,數(shù)據(jù)規(guī)模在幾十萬(wàn)和幾百萬(wàn)級(jí)別的時(shí)候見(jiàn)效最快酿炸,本來(lái)耗時(shí)50s的sql,在增加索引后可以提升到1~2s,而且不需要有代碼改動(dòng)瘫絮。 a.寫(xiě)sql的時(shí)候需要注意,索引字段和sql字段需要保持一致填硕,否則索引會(huì)無(wú)效麦萤。 b.不要在查詢(xún)=前面使用函數(shù),否則會(huì)導(dǎo)致索引不生效扁眯,舉個(gè)栗子壮莹,where str=substring(“hello world”,6,8),這樣是可以走索引的,但是 where substring(str,6,8)=“hello world” 是不會(huì)命中索引的 c. 建立索引的字段要區(qū)分度比較高姻檀,比如user表中有一個(gè)性別字段命满,性別字段無(wú)非男女兩種值,區(qū)分度不好绣版,建立索引效果不好胶台,要選擇區(qū)分度高的字段 d.建立組合索引,可以持續(xù)提升sql運(yùn)行效率杂抽,但是也不要盲目诈唬,同樣的要注意區(qū)分度,如果區(qū)分度不夠高缩麸,就不要加了铸磅,多個(gè)字段,盡可能把區(qū)分度高的字段放在前面杭朱,另外阅仔,還要注意索引長(zhǎng)度,這個(gè)索引要同時(shí)兼顧索引長(zhǎng)度和區(qū)分度的平衡 e.索引會(huì)大幅提升查詢(xún)效率弧械,但是也會(huì)損耗查詢(xún)后修改效率霎槐,要注意兼顧平衡,使用在一次插入梦谜,多次查詢(xún)的表上效果最好丘跌,同時(shí)要注意的是,組合索引會(huì)不可避免的增加索引長(zhǎng)度唁桩,會(huì)增加索引存儲(chǔ)空間闭树,注意索引長(zhǎng)度和區(qū)分度平衡 f.mysql支持全文索引,沒(méi)測(cè)試過(guò)效率荒澡,正常使用全文索引都是使用 lunce报辱,以及在其之上的solr和現(xiàn)在正火的elastisearch.
(2)分庫(kù)分表分區(qū)
分庫(kù),可以按照業(yè)務(wù)分庫(kù)单山,分流數(shù)據(jù)庫(kù)并發(fā)壓力碍现,使數(shù)據(jù)庫(kù)表更加有條理幅疼,把查詢(xún)庫(kù)和系統(tǒng)庫(kù)(增刪改比較頻繁的表)分開(kāi)了,這樣如果有大查詢(xún)昼接,不影響系統(tǒng)庫(kù)
分表爽篷,剛才說(shuō)了,索引適合應(yīng)對(duì)百萬(wàn)級(jí)別的數(shù)據(jù)量慢睡,千萬(wàn)級(jí)別數(shù)據(jù)量使用的好逐工,勉強(qiáng)也能湊合,但如果是上億級(jí)別的數(shù)據(jù)量漂辐,索引就無(wú)能為力了泪喊,因?yàn)閱嗡饕募赡芫鸵呀?jīng)上百兆或者更多了,那么髓涯,輪到我們的分表分區(qū)登場(chǎng)了.分表的方法有很多種: a袒啼、如果這個(gè)業(yè)務(wù)是有流程的,那么我們通常會(huì)設(shè)計(jì)一個(gè)歷史表或者歸檔表纬纪,用來(lái)存放歷史數(shù)據(jù)蚓再,這樣能保證實(shí)時(shí)數(shù)據(jù)效率比較高 b、針對(duì)某一張大表育八,可以根據(jù)查詢(xún)條件分成多張表,比如時(shí)間赦邻,我們可以將半個(gè)月或者10天的數(shù)據(jù)放到一張表里(看具體數(shù)據(jù)量髓棋,個(gè)人認(rèn)為3000W是個(gè)上限,最好控制到百萬(wàn)級(jí)別)惶洲,每過(guò)10天按声,我們就自動(dòng)創(chuàng)建一張數(shù)據(jù)庫(kù)表,然后將數(shù)據(jù)插入恬吕,如此签则,按照時(shí)間查詢(xún),就要先定位去那種表中去取數(shù)铐料,這樣渐裂,效率能夠得到大幅度提升,當(dāng)然钠惩,這么解決也有問(wèn)題柒凉,比如跨表,需要union多張表篓跛,而且跨表沒(méi)法支持索引 c膝捞、上面的方法是我們直接通過(guò)程序和數(shù)據(jù)庫(kù)實(shí)現(xiàn)的最原始的分表解決方案,現(xiàn)在市面上有一些成熟的軟件如mycat愧沟,也是支持分表的蔬咬,我們之前從事的公司有個(gè)專(zhuān)門(mén)做分布式數(shù)據(jù)庫(kù)的鲤遥,這些產(chǎn)品出現(xiàn)跨表,可以不使用程序union了林艘,而且還是使索引生效盖奈,但是需要對(duì)產(chǎn)品有一定的掌握 d、一般來(lái)講北启,數(shù)據(jù)庫(kù)中的大表畢竟只是一少部分卜朗,僅需要對(duì)這少部分大表進(jìn)行分表就可以了,沒(méi)必要小表也進(jìn)行分表咕村,增加維護(hù)開(kāi)發(fā)難度
分區(qū) 分區(qū)的實(shí)現(xiàn)道理和分表一樣场钉,也是將相應(yīng)規(guī)則的數(shù)據(jù)放在一起,唯一不同的是分區(qū)你只需要設(shè)定好分區(qū)規(guī)則懈涛,插入的數(shù)據(jù)會(huì)被自動(dòng)插入到指定的區(qū)里逛万,當(dāng)然查詢(xún)的時(shí)候也能很快查詢(xún)到需要區(qū),相當(dāng)于是分表對(duì)外透明了批钠,出現(xiàn)跨表數(shù)據(jù)庫(kù)自動(dòng)幫我們合并做了處理宇植,使用起來(lái)比分表更加方便,但是分區(qū)也有自己的問(wèn)題埋心,每一個(gè)數(shù)據(jù)庫(kù)表的并發(fā)訪(fǎng)問(wèn)是有上限的指郁,也就是說(shuō),分表能夠抗高并發(fā)拷呆,而分區(qū)不能闲坎,如何選擇,要考慮實(shí)際情況
(3)數(shù)據(jù)庫(kù)引擎
mysql比較常用的數(shù)據(jù)庫(kù)引擎有兩種茬斧,一種是innodb腰懂,一種是myisam.在測(cè)試一個(gè)千萬(wàn)級(jí)數(shù)據(jù)量復(fù)雜的sql測(cè)試,myisam的效率比innodb的快项秉,原因是:它的數(shù)據(jù)存儲(chǔ)結(jié)構(gòu)绣溜、索引存儲(chǔ)結(jié)構(gòu)和innodb不一樣,myisam的索引結(jié)構(gòu)是在內(nèi)存中存的娄蔼。
但myisam也有弱點(diǎn)怖喻,那就是他是表級(jí)鎖,而innodb是行級(jí)鎖岁诉。所以myisam適用于一次插入罢防,多次查詢(xún)的表,或者讀寫(xiě)分離中的讀庫(kù)中的表唉侄,而對(duì)于修改插入刪除操作比較頻繁的表咒吐,就很不適用了。
(4)預(yù)處理
一般來(lái)說(shuō),實(shí)時(shí)數(shù)據(jù)(當(dāng)天的數(shù)據(jù))還是比較有限的恬叹,真正數(shù)據(jù)量比較大的是歷史數(shù)據(jù)候生,基于大表歷史數(shù)據(jù)的查詢(xún),如果再涉及一些大表關(guān)聯(lián)绽昼,這種sql是非常難以?xún)?yōu)化的
a唯鸭、實(shí)時(shí)數(shù)據(jù)(當(dāng)天數(shù)據(jù))
通過(guò)對(duì)對(duì)業(yè)務(wù)的抽象,可以放在緩存里面硅确,提升系統(tǒng)運(yùn)行效率
b目溉、歷史數(shù)據(jù),大數(shù)據(jù)表歷史數(shù)據(jù)且有表關(guān)聯(lián)菱农,通過(guò)常規(guī)sql難以?xún)?yōu)化缭付,但是該數(shù)據(jù)通常有個(gè)共性,就是第二天去查詢(xún)前一天的數(shù)據(jù)做分析報(bào)表循未,也就是說(shuō)對(duì)時(shí)效性要求不高陷猫,這種情況的解決方案是預(yù)處理
(5) 在數(shù)據(jù)庫(kù)并發(fā)大的情況下,最好的做法就是進(jìn)行橫向擴(kuò)展的妖,增加機(jī)器绣檬,以提升抗并發(fā)能力,而且還兼有數(shù)據(jù)備份功能嫂粟。