1. 程式人生 > >Mysql性能調優

Mysql性能調優

字符類 group by 大連 2nf 不同的 更新問題 提升 不能 一個接一個

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性能調優