Mysql--- sql優化 + innodb引擎優化

一. 優化方案選擇

1.SQL本身的優化

1.1 從索引開始優化—提升SQL執行效率

1.1.1 B數索引

B數:小的放左邊,大的放右邊

索引建立原則:

A.頻繁更新的字段不適合

B.很少使用的效率

C.索引使用會降低寫操作的效

2. 選擇需要優化的sql ( 階段 )

選擇方法:優先選擇高併發低消耗的SQL:

A.1小時請求1W次,1次10個IO

B.1小時請求10次,1次1W個IO

即:A和B從單位時間產生的IO總數是相同的

  針對A 把10個io 減少到7個,則1小時減少3W個IO

  針對B 把1W個io減少到7K個,則1小時減少3W個IO

從系統性能上考慮,第一個SQL的優化能極大改善性能,第二個SQL慢一點無非也就是10個連接慢

3. 在索引中完成排序:

4.優化方法

  1. 使用最小的colum

4.2 Where 語句中的查詢條件不一定越多越好

  因爲where語句中只能使用一個索引列

4.3 避免使用複雜的join和子查詢

4.4 把複雜SQL拆分成簡單的小SQL ,在內存中處理數據

5.引擎參數合理配置優化

5.1.緩衝池innodb_buffer_pool_size :

官網:

https://dev.mysql.com/doc/refman/5.7/en/innodb-buffer-pool-resize.html

LRU算法。用於緩存索引的內存和實際的數據的空間,一般是系統內存的50% --70%左右

   該參數是在my.ini / my.cnf配置文件中設置,

查詢其大小:show global variables like 'innodb_buffer_pool_size';

如果是加載到緩存中是沒有IO操作的,索引對性能提升很大

5.1.1. 設置原則 調整InnoDB緩衝池大小

緩衝池innodb_buffer_pool_size大小必須是

緩衝塊innodb_buffer_pool_chunk_size  *

緩衝實例 innodb_buffer_pool_instances 結果的倍數

Buffer = N * ( block * instance * num )

如果配置不滿足倍數則緩衝池大小會自動調整爲等於innodb_buffer_pool_chunk_size * innodb_buffer_pool_instances 的倍數。

命令: SET GLOBAL innodb_buffer_pool_size = 3221225472

單位是bit

5.1.2  如何權衡配置innodb_buffer_pool_size大小

當前配置的innodb_buffer_pool_size是否合適,可以通過分析InnoDB緩衝池的性能來驗證。

可以使用以下公式計算InnoDB緩衝池性能:

Performance = innodb_buffer_pool_reads / innodb_buffer_pool_read_requests * 100

innodb_buffer_pool_reads:表示InnoDB緩衝池無法滿足的請求數。需要從磁盤中讀取。

innodb_buffer_pool_read_requests:表示從內存中讀取邏輯的請求數。

例如,在我的服務器上,檢查當前InnoDB緩衝池的性能:

5.1.2.1.緩存使用查詢

A.show status like 'innodb_buffer_pool_read%';

| Variable_name                         | Value       |

+---------------------------------------+-------------+

| Innodb_buffer_pool_read_ahead_rnd     | 0           |

| Innodb_buffer_pool_read_ahead         | 0           |

| Innodb_buffer_pool_read_ahead_evicted | 0           |

| Innodb_buffer_pool_read_requests      | 4029033624  |

| Innodb_buffer_pool_reads              | 91661       |

+---------------------------------------+-------------+

5 rows in set (0.00 sec)

5.1.2.2. 命中率

A.Innodb_buffer_pool_reads:表示InnoDB緩衝池無法滿足的請求數,需要從磁盤中讀取

B.Innodb_buffer_pool_read_requests:表示從內存中邏輯讀取的請求數

命中率= B / ( A + B )  * 100%

如果接近1 說明查詢的命中率很高,可以滿足緩衝池本身的大部分請求。從磁盤完成讀取的百分比非常小。因此無需增加innodb_buffer_pool_size值。

無需增大緩存,反之增加即可。

5.1.3. 什麼時候減小innodb_buffer_pool_size

在專用MySQL服務器上,多餘的innodb_buffer內存不會有問題,但是當使用共享服務器時,可能會有性能影響。因爲空閒內存對其他程序和操作系統很有用。

5.1.3.1.緩衝池的監控

可以使用SHOW ENGINE INNODB STATUS\G命令檢查內存池狀態:

mysql> show engine innodb status\G

Total large memory allocated 26386366464 //爲緩衝池分配的總內存(以字節爲單位)

Dictionary memory allocated 23826297//爲InnoDB數據字典分配的總內存(以字節爲單位

Buffer pool size   1572672

Free buffers       8192//緩衝池空閒列表的頁面總大小

Database pages     1553364 //緩衝池LRU列表的頁面總大小

Old database pages 573246//緩衝池舊LRU子列表的頁面總大小

Modified db pages  36//緩衝池舊LRU子列表的頁面總大小

Pending reads      0//等待讀入緩衝池的緩衝池頁數

Pending writes: LRU 0, flush list 0, single page 0

Pages made young 881819, not young 18198964

0.02 youngs/s, 0.05 non-youngs/s

Pages read 681064, created 2749237, written 3988300

0.02 reads/s, 0.12 creates/s, 11.50 writes/s

Buffer pool hit rate 1000 / 1000, young-making rate 0 / 1000 not 0 / 1000

Pages read ahead 0.00/s, evicted without access 0.00/s, Random read ahead 0.00/s

LRU len: 1553364, unzip_LRU len: 0

I/O sum[5152]:cur[0], unzip sum[0]:cur[0]

 

Free buffers :表示有多少空閒buffer。如果 此值長時間都較高,則可以考慮減小InnoDB緩衝池大小

InnoDB buffer pool 命中率:

InnoDB buffer pool 命中率 低於90%,則可以考慮增加innodb_buffer_pool_size

5.2.緩衝池實例 innodb_buffer_pool_instances

5.2.1.  作用

增加緩衝池的數量可以提高數據庫線程訪問的併發量,

  1. 查看引擎實例數量:SELECT @@innodb_buffer_pool_instances;

5.2.2. 設置原則

 A.最大爲64(最大值)。

B.僅當您設置innodb_buffer_pool_size爲1GB或更大的大小時,實例的配置設置纔會生效 。

C.指定的總大小在所有緩衝池之間分配。爲了獲得最佳效率,指定的組合 innodb_buffer_pool_instances 和innodb_buffer_pool_size,使得每個緩衝池實例是至少爲1GB。

官網提供:

https://dev.mysql.com/doc/refman/5.7/en/innodb-multiple-buffer-pools.html

5.3. 緩衝塊設置 innodb_buffer_pool_chunk_size

5.3.1.規則

 A.如果緩衝池等於(塊 * 實例個數)正整數倍,則引擎不會調整各值,結果取各自設置的原值

    Buffer = N * ( 塊 * 實例 )

B.如果緩衝塊 大於緩衝池的大小 則 緩衝塊 = 緩衝池 / 實例數量

規則:見5.1.1

 

5.4.sync_binlog:控制數據庫的binlog刷到磁盤上

查看值:select @@sync_binlog;

該參數控制着二進制日誌寫入磁盤的過程。

該參數的有效值爲0 1N

0:默認值。事務提交後,將二進制日誌從緩衝寫入磁盤,但是不進行刷新操作(fsync()),此時只是寫入了操作系統緩衝,若操作系統宕機則會丟失部分二進制日誌。

1:事務提交後,將二進制文件寫入磁盤並立即執行刷新操作,相當於是同步寫入磁盤,不經過操作系統的緩存。1是最安全的,但是也是最慢的。

N: 使執行N次寫入後,與硬盤同步

5.5.innodb_flush_log_at_trx_commit

查看值:select @@innodb_flush_log_at_trx_commit;

主要控制了innodblog buffer中的數據寫入日誌文件並flush磁盤的時間點。來修改事務日誌同步時機:如下

 

  1. innodb_flush_log_at_trx_commit=0 //每1秒鐘同步一次事務日誌文件
  2. innodb_flush_log_at_trx_commit=1// 每個事務完成之後同步一次事務日誌文件
  3. innodb_flush_log_at_trx_commit=2//事務完成後,寫到事務日誌文件中,等到日誌覆蓋再同步數據

 

建議:A的性能最差,B不能完全保證數據是寫到數據文件中,C

5.6. innodb_use_native_aio

InnoDB使用Linux上的異步I / O子系統(本機AIO)來執行數據文件頁面的預讀和寫入請求。此行爲由innodb_use_native_aio 配置選項控制,該選項僅適用於Linux系統,默認情況下處於 啓用狀態

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章