分享Mysql優化思路

一、總體優化思路

首先構建腳本觀察查詢數,連接數等數據,確定環境原因以及內部sql執行原因,然后根據具體原因做具體處理。

推薦:《mysql視頻教程

二、構建腳本觀察狀態

mysqladmin?-uroot?-p??ext?G

?

該命令可獲取當前查詢數量等信息,定時輪詢并將結果重定向到文本中,然后處理成圖表。

三、處理對策

1.若是規律性出現查詢慢,考慮緩存雪崩問題。

對于該問題只需將緩存的失效時間處理成不要相近時間同時失效,失效時間盡量離散化,或者集中到午夜失效。

2.若非規律性查詢緩慢,考慮設計缺乏優化

處理方法:

a:開啟profiling記錄查詢操作,并獲取語句執行詳細信息

show?variables?like?'%profiling%'; set?profiling=on; select?count(*)?from?user;? show?profiles; show?profile?for?query?1; >>> +--------------------------------+----------+ |?Status?????????????????????????|?Duration?| +--------------------------------+----------+ |?starting???????????????????????|?0.000060?| |?Executing?hook?on?transaction??|?0.000004?| |?starting???????????????????????|?0.000049?| |?checking?permissions???????????|?0.000007?| |?Opening?tables?????????????????|?0.000192?| |?init???????????????????????????|?0.000006?| |?System?lock????????????????????|?0.000009?| |?optimizing?????????????????????|?0.000005?| |?statistics?????????????????????|?0.000014?| |?preparing??????????????????????|?0.000017?| |?executing??????????????????????|?0.001111?| |?end????????????????????????????|?0.000006?| |?query?end??????????????????????|?0.000003?| |?waiting?for?handler?commit?????|?0.000015?| |?closing?tables?????????????????|?0.000011?| |?freeing?items??????????????????|?0.000085?| |?cleaning?up????????????????????|?0.000008?| +--------------------------------+----------+

?

b:使用explain 查看語句執行情況,索引使用,掃描范圍等等

mysql>?explain?select?count(*)?from?goods?G ***************************?1.?row?*************************** ???????????id:?1 ??select_type:?SIMPLE ????????table:?goods ???partitions:?NULL ?????????type:?index??? possible_keys:?NULL ??????????key:?gid ??????key_len:?5 ??????????ref:?NULL ?????????rows:?3 ?????filtered:?100.00 ????????Extra:?Using?index

?

c:相關優化手法

表的優化與列類型選擇

列選擇原則:

1:字段類型優先級 整型 > date,time > char,varchar > blob

原因:整型,time運算快,節省空間

char/varchar要考慮字符集的轉換與排序時的校對集,速度慢

blob無法使用內存臨時表

2:夠用就行,不要慷慨(如 smallint,varchar(N))

原因:大的字段浪費內存,影響速度

以varchar(10), varchar(300)存儲的內容相同,但在表聯查時,varchar(300)要花更多內存

3:盡量避免使用NULL

原因:NULL不利于索引,要用特殊的字節來標注.

在磁盤上占據的空間其實更大

索引優化策略

1.索引類型

1.1 B-tree索引(排好序的快速查找結構)

注:Myisam,innodb中,默認用的是B-tree索引

1.2 hash索引

在memory表里,默認是hash索引,hash的理論查詢時間復查度為O(1)

疑問:既然hash索引如此高效,為何不都用他?

a.hash函數計算后的結果是隨機的,如果是在磁盤上放置數據,以主鍵為id為例,那么隨著id的增長,id對應的行,在磁盤上隨機放置。

b.無法對范圍查詢進行優化

c.無法利用前綴索引,比如在b-tree中,field列的值為“helloworld”,索引查詢xx=hello/xx=helloworld都可以利用索引(左前綴索引),但hash索引無法做到,因為hash(hello)與hash(helloworld)并無關聯關系。

d.排序也無法優化

e.必須回行,通過索引拿到數據位置,必須回到表中取數據.

2.b-tree索引的常見誤區

2.1 在where條件常用的列上都加上索引

例:where cat_id=3 and price>100; //查詢第3個欄目,100元以上的商品

誤:cat_id和price上都加上索引。其實只能用上一個索引,他們都是獨立索引.

2.2 在多列上建立索引后,查詢哪個列,索引都將發揮作用

2.2 在多列上建立索引后,查詢哪個列,索引都將發揮作用

正解:多列索引上,索引發揮作用,需要滿足左前綴要求(層層索引)

以index(a,b,c)為例:

語句?索引是否發揮作用 where?a=3?是 where?a=3?and?b=5?是 where?a=3?and?b=5?and?c=4?是 where?b=3?or?where?c=4?否 where?a=3?and?c=4?a列能發揮索引作用,c列不能 where?a=3?and?b>10?and?c=7?a,b能發揮索引作用,c列不能

高性能索引策略

1.對于innodb而言,因為節點下有數據文件,因此節點的分裂將會變得比較慢,對于innodb的主鍵,盡量用整型,而且是遞增的整型。

2.索引的長度直接影響索引文件的大小,影響增刪改的速度,并間接影響查詢速度(占用內存多)。

3.針對列中的值,從左往右截取部分來建索引。

a.截的越短,重復度越高,區分越小,索引效果越不好

b.截的越長,雖然區分度提高,但索引文件變大影響速度

所以盡量在長度上找到一個平衡點使性能最大化,慣用手法:截取不同長度來測試索引區分度

區分度測試:?

select?count(distinct?left(word,?1))?/?count(*)?from?table;

測試完成后可以按測試得出的最優長度建立索引?

alter?table?table_name?add?index?word(word(4));

理想的索引

1.查詢頻繁

2.區分度高

3.長度小

4.盡量覆蓋常用查詢字段

? 版權聲明
THE END
喜歡就支持一下吧
點贊12 分享