MySQL性能優化方案總結

對MySQL進行優化主要能夠從如下幾個方面進行,
效果: SQL語句和索引 > 數據庫對象:表結構、字段類型、存儲引擎 > 配置 > 硬件
但成本從低到高。算法

1.SQL和索引優化

1.1SQL

1.1.1優化SQL語句的通常步驟:

①經過show status 命令瞭解各類SQL的執行效率,數據庫

show [session | global] status;

能夠根據須要加上參數來顯示session級(當前鏈接,默認)和global級(自數據庫上次啓動至今)的統計結果。
eg:緩存

show status like 'Com_%';

顯示當前鏈接全部統計參數的值。
Com_xxx表示每一個xxx語句執行的次數,一般須要注意的是下面幾個參數:
Com_select/Com_insert/Com_update/Com_delte。服務器

②定位執行效率較低的SQL語句
·經過show processlist命令實時查看當前SQL的執行狀況;
·經過慢查詢日誌(結束之後記錄)定位出現的問題。網絡

③經過explain 或 desc分析低效SQL的執行計劃
select_type(simple/primary/union/subquery)/table/type/possible_keys/key/key_len/rows/extrasession

④經過show profile 分析SQL
show profile 能幫咱們瞭解時間都耗費到哪裏去了。
MySQL從5.0.37版本開始增長了show profile和show profiles語句的支持,
經過secect @have_profiling命令可以看到當前MySQL是否支持profile,
經過show profiles咱們可以更清楚瞭解SQL執行的過程,
經過show profile for query咱們能看到執行過程當中線程的每一個狀態和消耗的時間。架構

⑤經過trace分析優化器如何選擇執行計劃
MySQL5.6提供了對SQL的跟蹤trace,能幫咱們瞭解爲何優化器選擇執行A計劃而不是B計劃,進一步理解優化器的行爲。併發

⑥肯定問題並採起相應的優化措施負載均衡

1.1.2兩個簡單實用的優化方法

①按期分析和檢查表高併發

analyze table tbl_name;
check table tbl_name;

②按期優化表

optimize table tbl_name;

1.1.3經常使用SQL的優化

①優化insert語句
·若是從同一客戶端插入不少行,應該儘可能使用多個值表一次性插入;
·若是從不一樣客戶端插入不少行,可使用insert delayed語句先把數據放在內存的隊列中,並不真正寫入磁盤,比每條語句分別插入快得多;
·當從一個文本文件裝載一個表時,使用load data infile,這一般比使用不少insert 語句快20倍;
·若是在MyISAM表中進行批量插入,能夠經過增長bulk_insert_buffer_size變量值的方法來提升速度。

②優化 order by語句
MySQL中有兩種排序方式,第一種經過有序索引順序掃描直接返回有效數據,不須要額外的排序,操做效率較高;第二種對返回的數據進行排序,也就是常說的Filesort排序,全部不是經過索引直接返回排序結果的排序都是filesort排序。
優化目標:儘可能經過索引直接返回有序數據,減小額外的排序。
經過建立合適的索引能減小filesort出現,可是某些狀況下,條件限制不能讓filesort消失,那就須要想辦法加快filesort的操做。filesort有兩種排序算法,一種是一次掃描算法(較快),二種是兩次掃描算法。適當加大系統變量max_length_for_sort_data的值,可以讓MySQL選擇更優化的filesort排序算法;適當加大sort_buffer_size排序區,儘可能讓排序在內存中完成,而不是經過建立臨時表放在文件中進行。儘可能只使用必要的字段,select具體的字段名稱,而不是select * 選擇全部字段,這樣能夠減小排序區的使用,提升SQL性能。

③優化group by 語句
MySQL默認對全部group by col1,col2...的字段進行排序,能夠指定order by null禁止排序。

④優化嵌套查詢
MySQL5.5及如下版本,子查詢的效率不如鏈接查詢(join),由於MySQL不須要在內存中建立臨時表來完成這個在邏輯上須要兩個步驟的查詢工做。

⑤優化or 查詢
對於含有or的查詢子句,若是要利用索引,則or之間的每一個條件列都必須使用索引;若是沒有索引,能夠考慮增長索引。
MySQL在處理含有or的查詢時,實際上對or的各個字段分別查詢後的結果進行了union操做。

⑥優化分頁查詢
·第一種 在索引上完成排序分頁操做,而後根據主鍵關聯回原表查詢所須要的其餘列的內容;
·第二種 在排序字段不會出現重複值的狀況下,新增一個參數記錄上次查詢的最後一條記錄,將limit m,n轉化成limit n.

⑦使用SQL提示
就是在SQL語句中加入一些認爲提示,讓MySQL按照特定方案執行,以達到優化操做的目的。
·use index 指定MySQL參考的索引而忽略別的索引
·ignore index 讓MySQL忽略某個或某些索引
·force index 強制MySQL使用某個特定的索引

⑧其餘
·使用REGEXP,好比代替like.
·使用rand()提取隨機行
·表的字段儘可能不使用自增加變量,在高併發的狀況下可能會對MySQL的效率有較大影響。

1.2索引優化

MySQL的索引在存儲引擎層實現,而不是在服務器層。
能夠經過show status like 'Handler_read%'命令來查看索引使用狀況。

1.2.1MySQL 中索引的存儲類型

MySQL 中索引的存儲類型目前有四種(B-Tree、Hash、空間索引R-Tree、全文索引Full-text),具體和表的存儲引擎相關;MyISAM 和 InnoDB 存儲引擎都支持 B-Tree 和全文索引(Full-text,InnoDB 5.6 +);MyISAM還支持空間索引(R-Tree);Memory/Heap存儲引擎能夠支持 HASH和 B-Tree 索引,不過只有Memory/Heap支持 Hash索引。

1.2.2MySQL如何使用索引

(1)MySQL使用索引的典型情景
①匹配全值(match the full value)
②匹配值的範圍(match a range of values)
③匹配最左前綴(match a leftmost prefix)最左匹配原則是MySQL中B-Tree索引使用的首要原則。
④只查詢索引(index only query)固然where子句中要知足最左匹配原則
⑤匹配列前綴(match a column prefix)使用複合索引的第一列的開頭一部分
⑥複合索引中,一部分匹配精確內容 and 其餘部分匹配一個範圍(match one part exactly and match a range on another part)
⑦列名是索引,那麼column_name is null就會使用索引,好比where column_name is null
(2)MySQL不使用索引的典型情景
①like "%query"不使用B-Tree索引,但like "query%"會使用B-Tree索引。
②數據類型出現隱式轉換的時候也不會使用索引。尤爲當列類型是字符串時,必定記得在where條件中把字符串常量值用引號引發來,好比where last_name = '1';
③使用複合索引時,查詢條件不包含索引的最左邊部分
④用or 分割的條件,若是其中一個列中沒有索引,則涉及的另外一個索引也不會被用到。
⑤若是MySQL估計使用索引比全表掃描更慢,則不使用索引。

2.優化數據庫對象:表結構、字段類型、存儲引擎

2.1表結構

2.1.1三範式和反三範式

2.1.2分區、分表(對錶進行水平或者垂直拆分)

2.2字段選擇合適的數據類型

procedure analyse() 能夠對當前應用的表進行分析,對數據表中列的數據類型提出優化建議。

2.3選擇合適的存儲引擎

3.優化MySQL server

3.1MySQL內存管理和優化

3.2InnoDB log機制及優化

3.3調整跟併發相關的MySQL參數

(1)max_connections
(2)back_log
(3)table_open_cache
(4)thread_cache_size
(5)innodb_lock_wait_timeout

4.磁盤I/O優化

4.1使用磁盤陣列(RAID)

4.2使用Linux虛擬文件卷模擬RAID

4.3符號鏈接(Symbolic Links)分佈I/O

利用操做系統的符號鏈接(Symbolic Links)將不一樣的數據庫、表或索引指向不一樣的物理磁盤,從而達到分佈磁盤I/O的目的。

4.4禁止操做系統更新文件的atime屬性

4.5用裸設備(Raw Device)存放InnoDB的共享表空間

4.6調整I/O調度算法

4.7RAID卡電池的充放電引發的性能波動

4.8NUMA架構優化

非一致存儲訪問結構(Non-Uniform Memory Access, NUMA)

5.應用優化

5.1使用鏈接池

5.2減小對MySQL的訪問

①理清應用邏輯,能一次取出的數據不用兩次;
②使用查詢緩存
MySQL的查詢緩存(MySQL query cache)是4.1版本以後新增的功能,做用是存儲select的查詢文本和相應結果。若是隨後收到一個相同的查詢,服務器會從查詢緩存中從新獲得查詢結果,而再也不須要解析和執行查詢。
查詢緩存適用於更新不頻繁的表,當表更改(包括表結構和數據)後,查詢緩存會被清空。
③在應用端增長cache層

④負載均衡負載均衡(Load Balance)是實際應用中使用很是廣泛的一種優化方法,它的機制就是利用某種均衡算法,將固定的負載量分佈到不一樣的服務器上,以此來減輕單臺服務器的負載,達到優化的目的。負載均衡能夠用在系統中的各個層面中,從前臺的 Web 服務器到中間層的應用服務器,最後到數據層的數據庫服務器,均可以使用。·利用 MySQL 複製分流查詢和更新操做利用 MySQL 的主從複製能夠有效地分流更新操做和查詢操做,具體的實現是一個主服務器承擔更新操做,而多臺從服務器承擔查詢操做,主從之間經過複製實現數據的同步。經過複製來分流查詢和更新是減小主數據庫負載的一個經常使用方法,可是這種辦法也存在一些問題,最主要的問題是當主數據庫上更新頻繁或者網絡出現問題的時候,主從之間的數據可能存在比較大的延遲更新,從而形成查詢結果和主數據庫上有所差別。所以在設計應用的時候須要有所考慮。

相關文章
相關標籤/搜索