MySql數(shù)據(jù)庫(kù)優(yōu)化

字段優(yōu)化

  • 表字段 not null,因?yàn)?null 值很難查詢(xún)優(yōu)化且占用額外的索引空間,推薦默認(rèn)數(shù)字 0。
  • 數(shù)據(jù)狀態(tài)類(lèi)型的字段,比如 status, type 等等,盡量不要定義負(fù)數(shù),如 -1。因?yàn)檫@樣可以加上 UNSIGNED,數(shù)值容量就會(huì)擴(kuò)大一倍。
  • 可以的話(huà)用 TINYINT、SMALLINT 等代替 INT,盡量不使用 BIGINT,因?yàn)檎嫉目臻g更小。
  • 字符串類(lèi)型的字段會(huì)比數(shù)字類(lèi)型占的空間更大,所以盡量用整型代替字符串,很多場(chǎng)景是可以通過(guò)編碼邏輯來(lái)實(shí)現(xiàn)用整型代替的。
  • 字符串類(lèi)型長(zhǎng)度不要隨意設(shè)置,保證滿(mǎn)足業(yè)務(wù)的前提下盡量小。
  • 用整型來(lái)存 IP。
  • 單表不要有太多字段,建議在20以?xún)?nèi)。
  • 為能預(yù)見(jiàn)的字段提前預(yù)留,因?yàn)閿?shù)據(jù)量越大,修改數(shù)據(jù)結(jié)構(gòu)越耗時(shí)。

索引設(shè)計(jì)

索引,空間換時(shí)間的優(yōu)化策略,基本上根據(jù)業(yè)務(wù)需求設(shè)計(jì)好索引,足以應(yīng)付百萬(wàn)級(jí)的數(shù)據(jù)量,養(yǎng)成使用 explain 的習(xí)慣,關(guān)于 explain 也可以訪問(wèn):explain 讓你的 sql 寫(xiě)的更踏實(shí)了解更多。

  • 一個(gè)常識(shí):索引并不是越多越好,索引是會(huì)降低數(shù)據(jù)寫(xiě)入性能的。
  • 索引字段長(zhǎng)度盡量短,這樣能夠節(jié)省大量索引空間;
  • 取消外鍵,可交由程序來(lái)約束,性能更好。
  • 復(fù)合索引的匹配最左列規(guī)則,索引的順序和查詢(xún)條件保持一致,盡量去除沒(méi)必要的單列索引。
  • 值分布較少的字段(不重復(fù)的較少)不適合建索引,比如像性別這種只有兩三個(gè)值的情況字段建立索引意義不大。
  • 需要排序的字段建議加上索引,因?yàn)樗饕菚?huì)排序的,能提高查詢(xún)性能。
  • 字符串字段使用前綴索引,不使用全字段索引,可大幅減小索引空間。

編寫(xiě)習(xí)慣

  • 查詢(xún)不使用 select *,盡量查詢(xún)帶索引的字段,避免回表。
  • 盡量使用 limit 對(duì)查詢(xún)數(shù)量進(jìn)行限制。
  • 查詢(xún)字段盡量落在索引上,尤其是復(fù)合索引,順序很重要。
  • 拆分大的 delete / insert 操作,一方面會(huì)鎖表,影響其他業(yè)務(wù)操作,還有一方面是 MySQL 對(duì) sql 長(zhǎng)度也是有限制的。
  • 不建議使用 MySQL 的函數(shù),計(jì)算等,可先由程序處理,從上面提的一些點(diǎn)會(huì)發(fā)現(xiàn),能交由程序處理的盡量不要把壓力轉(zhuǎn)至數(shù)據(jù)庫(kù)上。
  • 查詢(xún) count,性能:count(1) = count(*) > count(主鍵) > count(其他字段)。
  • 查詢(xún)操作符能用 between 則不用 in,能用 in 則不用 or。
  • 避免使用 != 或 <>、IS NULL 或 IS NOT NULL、IN ,NOT IN 等這樣的操作符,因?yàn)檫@些查詢(xún)可能進(jìn)行全表掃描。
  • sql 盡量簡(jiǎn)單,少用 join,不建議兩個(gè) join 以上。

分區(qū)

分區(qū)是根據(jù)一定的規(guī)則,數(shù)據(jù)庫(kù)把一個(gè)表分解成多個(gè)更小的、更容易管理的部分,是一種水平劃分。對(duì)應(yīng)用來(lái)說(shuō)是完全透明的,不影響應(yīng)用的業(yè)務(wù)邏輯,即不用修改代碼。因此能存更多的數(shù)據(jù),查詢(xún),刪除也支持按分區(qū)來(lái)操作,從而達(dá)到優(yōu)化的目的。如果有考慮分區(qū),可以提前做準(zhǔn)備,避免下列一些限制:

  • 一個(gè)表最多只能有1024個(gè)分區(qū)(mysql5.6之后支持8192個(gè)分區(qū))。
  • 如果分區(qū)字段中有主鍵或者唯一索引列,那么所有主鍵列和唯一索引列都必須包含進(jìn)來(lái),如果表中有主鍵或唯一索引,那么分區(qū)鍵必須是主鍵或唯一索引。
  • 分區(qū)表中無(wú)法使用外鍵約束。
  • NULL值會(huì)使分區(qū)過(guò)濾無(wú)效。
  • 目前mysql不支持空間類(lèi)型和臨時(shí)表類(lèi)型進(jìn)行分區(qū)。不支持全文索引。
  • 所有分區(qū)必須使用相同的存儲(chǔ)引擎。

分區(qū)可按以下四種類(lèi)型分區(qū):

  • RANGE表分區(qū):范圍表分區(qū),按照一定的范圍值來(lái)確定每個(gè)分區(qū)包含的數(shù)據(jù);
  • LIST表分區(qū):列表表分區(qū),按照一個(gè)一個(gè)確定的值來(lái)確定每個(gè)分區(qū)包含的數(shù)據(jù);
  • HASH表分區(qū):哈希表分區(qū),按照一個(gè)自定義的函數(shù)返回值來(lái)確定每個(gè)分區(qū)包含的數(shù)據(jù);
  • KEY表分區(qū) :key表分區(qū),與哈希表分區(qū)類(lèi)似,只是用MySQL自己的HASH函數(shù)來(lái)確定每個(gè)分區(qū)包含的數(shù)據(jù)。

分表

分表分水平分表和垂直分表。

  • 水平分表即拆分成數(shù)據(jù)結(jié)構(gòu)相同的各個(gè)小表,如拆分成 table1, table2...,從而緩解數(shù)據(jù)庫(kù)讀寫(xiě)壓力。
  • 垂直分表即將一些字段分出去形成一個(gè)新表,各個(gè)表數(shù)據(jù)結(jié)構(gòu)不相同,可以?xún)?yōu)化高并發(fā)下鎖表的情況。

可想而知,分表的話(huà),程序的邏輯是需要做修改的,所以,一般是在項(xiàng)目初期時(shí),預(yù)見(jiàn)到大數(shù)據(jù)量的情況,才會(huì)考慮分表。后期階段不建議分表,成本很大。

分庫(kù)

分庫(kù)一般是主從模式,一個(gè)數(shù)據(jù)庫(kù)服務(wù)器主節(jié)點(diǎn)復(fù)制到一個(gè)或多個(gè)從節(jié)點(diǎn)多個(gè)數(shù)據(jù)庫(kù),主庫(kù)負(fù)責(zé)寫(xiě)操作,從庫(kù)負(fù)責(zé)讀操作,從而達(dá)到主從分離,高可用,數(shù)據(jù)備份等優(yōu)化目的。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容