Mysql性能調優
1. 宏觀上調優可以考慮三個部分,分別為硬件、網絡、軟件,此處主要考慮軟件調優
(1)軟件調優包括:表設計(範式、字段類型、數據存儲引擎)、SQL語句語索引、配置文件參數、文件系統、操作系統、MYSQL版本、體系架構
2. 表設計
(1) 第一範式(1NF):數據庫表中的字段都是單一屬性的,不可再分。這個單一屬性由基本數據類型構成,包括整型、字符型、邏輯型、日期型等。(只要是關系型數據庫都符合第一範式)
(2) 第二範式(2NF):要求實體的屬性完全依賴於主關鍵字,即只能有一個主關鍵字。也即非關鍵字段都依賴於主鍵
(3) 第三範式(3NF):不存在非關鍵字段對任一候選關鍵字段的傳遞函數依賴。
3. 字段類型的選擇:一般原則是保小不保大,能用占字節少的字段就不用大字段。
3.1 數值類型
(1)錄入手機號碼用bigint
(2)IP地址可以采用unsigned int整型,並采用INET_NTOA()負責將數字轉換為IP地址,INET_ATON()負責將IP地址轉換為數字
(3)根據需要選擇最小整數類型
3.2 字符類型
(1)計算varchar的最大長度:varchar(32766)
3.3 時間類型
4. 采用更合適的鎖機制
4.1 MYSQL的鎖分為三種:
(1)表級鎖:開銷小、加鎖快,不會出現死鎖;鎖粒度大,發生沖突的概率最高,並發度最低。MyISAM引擎
(2)行級鎖:開銷大、加鎖慢、會出現死鎖;鎖粒度最小,發生沖突的概率最低,並發度最高。InnoDB引擎
(3)頁面鎖:介於中間。NDB引擎
4.2 MyISAM引擎:
(1)對MyiSAM表的讀操作(加讀鎖),其它進程可以讀,但是會阻塞同一表的寫操作;
(2)對MyISAM表的寫操作,會阻塞其它線程對同一表的讀寫操作,只有當寫鎖釋放後,才會執行其它進程的讀寫操作;
4.3 InnoDB引擎:InnoDB存儲引擎是通過給索引上的索引項加鎖來實現的,這說明只有通過索引條件檢索數據,InnoDB才會使用行級鎖,否則,InnoDB將采用表鎖 (為防止在高並發訪問下,大量事務因無法立即獲得所需的鎖而掛起,會占用大量計算機資源,造成嚴重的性能問題,這時可以通過設置合適的鎖等待超時閾值參數innode_lock_wait_timeout來解決,一般設置為100s)
5 選擇合適的事務隔離級別
5.1 事務的屬性:
(1)原子性
(2)一致性
(3)隔離性
(4)持久性
5.2 不確定的讀取情況
(1)臟讀:一個事務開始讀取某行數據,另外一個事務已經更新了此數據但沒有及時提交。而另一事務可能發生回滾。
(2)不可重復讀:一個事務對同一行數據重復讀取兩次,但是得到了不同的結果。例如,在兩次讀取的途中,有另外一個事務對該行的數據進行了修改並提交。
(3)兩次更新問題:無法重復讀取的特例。兩個並發事務同時讀取同一行數據,然後其中一個對它進行修改提交,而另一個也進行了修改提交。這就造成第一次寫操作失效
(4)幻讀:事務在操作過程中進行了兩次查詢,第二次查詢的結果包含了第一次查詢中未出現的數據。這是因為在兩次查詢過程中有另外一個事務插入數據。
5.3 InnodDB 事務隔離級別
(1)Read Uncommitted 讀未提交:會產生臟讀取。(“排他寫鎖”)
(2)Read Committed 讀提交:會產生不可重復讀取。(“瞬間共享讀鎖”和“排他寫鎖”)
(3)Repeated Read 可重復讀取:會產生幻讀。(“共享讀鎖”和“排他寫鎖”)
(4)Serilizable 序列化:提供嚴格的事務隔離,事務嚴格序列化,事務只能一個接一個地執行,不能並發執行。
6. SQL優化與合理利用索引
6.1 通過開啟慢日誌來定位執行很慢的SQL語句:(explain優化器查詢)
開啟慢日誌的方法:在my.cnf配置文件中,加入以下參數:
slow_query_log=1
slow_query_log_file=mysql.slow
long_query_time=2(超過2秒的SQL會記錄下來)
6.2 SQL優化案例分析
(1)not in 子查詢優化:盡量避免子查詢,采用left join表連接
(2)模式匹配like ‘%xxx%‘: 在MYSQL中,like ‘xxx%’ 可以用到索引,而like ‘%xxx%‘則不行;利用覆蓋索引來進行優化
(3)limit分頁優化
(4)count(*)統計數據如何加快速度:利用輔助索引count(輔助索引)快於count(*);
(5)SQL語句中有or條件,則會用不到索引;將其改為union all結果集合並
(6)不必要的排序;
(7)不必要的嵌套select查詢
(8)不必要的表自身連接、
(9)用where子句代替having子句
6.3 合理使用索引:索引有一定開銷,例如寫入和更新或刪除操作時都需要更新索引。此外,只有當某列被用於where子句時,才能享受到索引性能提升的好處
(1)單列索引和聯合索引的對比:聯合索引遵循最左側原則
(2)字段使用函數,將不能用到索引
(3)致命的無引號導致全表掃描,無法用到索引:
(4)當取出的數據量超過表中數據的20%時,優化器就不會使用索引,而是全表掃描
(5)考慮不為某些列建立索引:
(6)group by、order by優化
(7)MYSQL5.6 InnoDB引擎支持全文索引
(8)MYSQL5.6支持explain update/select
(9)MySQL5.6優化了index merge合並索引,即可以實現一條SQL可以使用兩個索引了
7. my.cnf配置文件調優
7.1 per_thread_buffers優化:為每個連接到MySQL的用戶進程分配內存
(1)read_buffer_size: 用於表的順序掃描,表示每個線程分配的緩沖區大小。
(2)read_rnd_buffer_size: 用於表的隨機讀取,表示每個線程分配的緩沖區大小
(3)sort_buffer_size: 在表進行order by 和group by 排序操作時,由於排序的字段沒有索引,會出現Using filesort,為了提高性能,可用此參數增加每個線程分配的緩沖區大小。
(4)thread_stack: 表示每個線程的堆棧大小
(5)join_buffer_size:
(6)max_connections: 該參數用來設置最大連接數,默認100。一般設置為512到1000即可。
7.2 global_buffers優化:用於在內存中緩存從數據文件中檢索出來的數據塊,可以大大提高查詢和更新數據的性能。
(1)innodb_buffer_pool_size: 核心參數,默認為128MB
(2)innodb_additional_mem_pool_size:用來存儲數據字典信息和其他內部數據結構,表越多,需要分配的內存越多,一版設置為16MB
(3)innodb_log_buffer_size: 事務日誌所使用的緩沖區。
7.3 Query Cache在不同環境下的使用: 其功能是緩存select語句和結果集。查詢緩存絕不會返回過期數據,當數據被修改後,在查詢緩存中的任何相關詞條都會被清除。
如果環境中寫操作很多,不適合打開query_cache_type,如果讀操作頻繁而寫操作很少,則打開query_cache_type=1。
Mysql性能調優