1. 程式人生 > >mysql 優化(3)

mysql 優化(3)

max deadlock 頻率 nim sem 並發 內存 同時 redo log

using filesort 不能利用索引來進行分組或排序,利用filesort算法在內存或者磁盤進行排序
using temporary 先在內存中進行分組,歸並等操作,不夠利用磁盤

SELECT id FROM table ORDER BY RAND() LIMIT n;
優化成=&get;
SELECT id FROM table t1 JOIN (SELECT RAND() * (SELECT MAX(id) FROM table) AS nid) t2 ON t1.id &get; t2.nid LIMIT n;

兩個表left join,一般不會被改寫順序,
而三個以上的left join他們之間也會自動選擇順序了

SQL優化要點
1、 消除type = ALL
2、 消除 using filesort
3、 消除 using temporary
4、 多表連接時,註意連接順序是否我們提交的順序,是否被改寫了(有時候,被改寫了反而更好,不一而論)
5、 註意 key_len 是否達到了預期,整個聯合索引盡可能都被利用
其他優化建議
• 使用長連接避免連接開銷。或者加大thread_cache_size,或者使用thread pool;
• 重要業務上線前,關鍵SQL必須逐個EXPLAIN分析,確保都有適當的索引;
• 請求頻率很高的表上禁止運行長讀寫事務,避免發生嚴重鎖等待等性能問題;
• 類似長URL(低於255長度)列檢索,建議先進行HASH後創建索引,其檢索效率會高很多倍;
• 區分冷熱表,讓熱數據盡可能放在buffer中,提高讀寫效率;
• 如果需要經常統計結果,建議新增計數器,或者使用redis、mc來代替MySQL;
• 非精確性統計表總記錄數時,可以執行SHOW TABLE STATUS查看估算結果;
• 所有列類型都設置默認值,嚴禁允許默認為NULL值的;
• 如果不能把多個大字段(長VARCHAR、TEXT、BLOB類型)分離到子表的話,就想辦法合並成一個大字段,避免頻繁的off-page;
• 個別時候可能需要采用冗余字段來存儲,比如部分長度(尤其是取最右邊的長度),或者反向存儲,方便特殊的檢索需求;
• 頻繁讀取的熱數據,盡可能緩存在redis、mc中,哪怕只緩存10秒,如果每秒請求1000次的話,也可以減少1萬次請求;
• 可以的話,采用多行記錄同時INSERT,或者LOAD方式批量寫入,提高寫入效率,但也要避免鎖時間太久的問題;

Index Condition Pushdown(ICP)
• 5.6以上,優化索引查詢效率
• 以前:先檢索全部記錄,而後進行一次過濾
• 現在:邊檢索記錄,邊進行過濾
• 好處:降低SQL層得到的結果集,提高處理效率
• 優化支持range、ref、eq_ref、eq_or_null類型查詢
• 查詢優化器提示:Using index condition

• 在不支持ICP之前,MySQL進行索引查詢時,會先根據索引查詢記錄,再根據WHERE條件來進行過濾。
• 在支持ICP後,MySQL在根據索引查找的同時,會根據WHERE條件對結果進行過濾,將WHERE條件的過濾操作放在存儲引擎層,這樣一來,
在一些查詢中,ICP會大大提高上層SQL層(SERVER層)讀取記錄(fetch)效率,從而提高整體tps。

show global variables like ‘optimizer_switch‘;
啟用ICP:
set global optimizer_switch = "index_condition_pushdown=on";
關閉ICP:
set global optimizer_switch = "index_condition_pushdown=off";

新特性:MRR & BKA
MRR(Multi-Range Read)
• 5.6以上,減少磁盤隨機訪問,將隨機訪問轉變成順序訪問,提高IO性能
• 適用於range、ref、eq_ref類型查詢
• 數據訪問較為順序,查詢輔助索引時,對查詢結果先按照主鍵(ROWID)進行排序,並按照主鍵排序後的順序,進行順序查找
• 減少buffer pool中的頁面被替換次數
• 批量處理對索引的查詢操作
MRR工作方式:
• 將查詢到的輔助索引鍵值放在一個緩沖中,這時緩沖中的數據是根據輔助所以進行排序的
• 將緩沖中的鍵值根據 ROWID進行排序
• 根據ROWID的排序順序來訪問實際的數據文件

新特性 BKA(Batched Key Access)
在MySQL 5.6中,BKA(Batched Key Access)聯接算法可同時用於表連接以及join buffer時的索引訪問。
BKA算法支持inner join、outer jon、semi-join,以及nested-outer join。BKA算法使得表掃描效率更高,以此實現JOIN優化。
此前BNL(Block Nested-Loop)聯接算法只能用於inner join優化,現在也支持outer join、semi join、以及nested outer join等。

InnoDB引擎優化 - innodb buffer pool轉儲、預熱
轉儲文件名為ib_buffer_pool, 轉儲的文件中只記錄了space id和page no,所以非常小
InnoDB引擎優化 - read only transaction,只讀事務
默認開啟事務是READ WRITE,可以在開啟事務時指定: START TRANSACTION READ ONLY;
如果以autocommit運行select,則視其為READ ONLY
只讀事務不會為其創建事務,提高只讀效率,只讀事務減少了創建read view的開銷,因為這是個全局鎖競爭的熱點。
InnoDB引擎優化 - 物化Innodb表的統計信息
控制選項:innodb_stats_persistent
當開啟該選項後,就會將表的統計信息記錄到ibdata中,只有手動執行ANALYZE TABLE才會對其進行更新。
在5.6中,引入的一個新參數innodb_stats_auto_recalc用於控制是否進行自動統計信息計算。當表上的記錄修改超過1/16比例,或者總共超過20億行時,
或者訪問information_schema下的一些特定表,就會對統計信息重新計算;這只對在建表時打開了innodb_stats_persistent或者指定了建表選項STATS_PERSISTEND=1生效,
采樣page的個數通過參數innodb_stats_persistent_sample_pages來控制(實際讀取的page數會大於該值)。

information_schema.TABLES
information_schema.STATISTICS
information_schema.PARTITIONS
information_schema.KEY_COLUMN_USAGE
information_schema.TABLE_CONSTRAINTS
information_schema.REFERENTIAL_CONSTRAINTS

InnoDB引擎優化 - 引入獨立page cleaner thread和purge thrad
啟用獨立的page cleaner線程和 purge thread,通過選項 innodb_puge_threads 來控制。在5.6版本下,還只能設置為1,從5.7開始,就可以設置成更大值
InnoDB引擎優化 - 死鎖檢測增強
啟用 innodb_print_all_deadlocks 選項,即可將全部死鎖信息打印輸出到日誌文件中,在以前,只能在show engine innnodb status中打印最後一次死鎖信息
InnoDB引擎優化 - 獨立undo表空間
innodb_undo_tablespaces #undo 表空間的個數,將所有的回滾段平分到這麽多個ibd表空間文件中,這個值一旦設置,則不可更改。
配置這個及下面的選項,是為&get;了將undolog從Ibdata中獨立出來,並且由於undo log是隨機寫,可以放到SSD盤上來提高性能
innodb_undo_directory #表示undo log表空間文件的路徑,啟動前設置
innodb_undo_logs #等同於老版本的innodb_rollback_segments,一個事務中最多可以多少個回滾段。
InnoDB引擎優化 - InnoDB page size增強
支持4K、8K格式,適用於絕大多數行平均大小較低值的場景。
從5.7開始,則新增支持32K、64K格式,以適應數據倉庫中長日誌格式場景。

InnoDB引擎優化 - page checksum增強
innodb_checksum = 0|1,是否校驗innodb磁盤文件
innodb_checksum_algorithm #更快的checksum算法(crc32), innodb|crc32|none|strict_innodb|strict_crc32|strict_none
binlog_checksum = CRC32 | NONE,校驗算法
master_verify_checksum = 0|1,讀取binlog時,是否校驗
slave_sql_verify_checksum = 0|1,在slave上讀取relay log時,是否校驗relay log

5.6新特性:EXPLAIN增強
支持DML的EXPLAIN,但是需要註意可能有不準確的情況。
EXPLAIN結果中,type列有時候會變成range,但實際上是use index的,和改成SELECT後的執行計劃不一致。
而如果是多表的DML執行計劃解析,則沒有問題。

5.6新特性:查詢優化器跟蹤
啟用了optimizer_trace功能,和oracle的執行計劃類似,可以輸出json格式結果,並且開始往CBO方向靠。
http://imysql.com/2014/08/05/a-fake-bug-with-eq-range-index-dive-limit.shtml
http://blog.163.com/li_hx/blog/static/18399141320147521735442/

show tables like ‘INNODB_SYS_%‘;

5.6新特性:復制增強
1、 開始支持GTID,極大方便了復制的便利性以及可靠性;
2、 支持多線程並發復制,不過只能是基於database級別的,意義不大,可以用percona或者mariadb分支特性;
3、 slave庫延遲更新,防止誤操作;
4、 binlog_row_image = full|minimal|noblob,減少binlog大小;同時binlog和relay log也支持crash safe了,上面checksum已介紹過;
5、 支持將master、slave、relay log info等信息記錄在innodb表中,取代原先的寫文件做法,提高可靠性;
6、 可以利用mysqlbinlog構建一個binlog server:--read-from-remote-server --raw
7、 binlog group commit
Tips:當引入binlog group commit後,sync_binlog的含義就變了,假定設為1000,表示的不是1000個事務後做一次fsync,而是1000個事務組。

5.7新特性:其他
innodb_purge_threads 可以設置大於1,有效的進行purge
InnoDB REDO log size up to 512 Gbyte (日誌大小達到了512G,有效的提高了檢查點的寫入)

mysql選擇,percona,mariadb
Percona分支特有選項/參數
enforce_storage_engine
expand_fast_index_creation
² 擴展快速創建索引特性,盡可能避免在一些場景下執行唯一約束、外鍵約束檢查,提高性能
² mysqldump中新增選項 --innodb-optimize-keys,在備份文件最莫問再加上enable keys,以及唯一約束、外鍵約束檢查等
extra_max_connections
extra_port
² thread pool功能的擴展,允許使用額外端口和線程作為管理員救命用
innodb_kill_idle_transaction
² 0(不啟用)/N秒,幹掉超過N秒的事務(不光是只讀查詢)
innodb_log_block_size
² 默認512字節,可以調整成4K,以適應SSD設備,提高IO性能
innodb_show_locks_held
² 在SHOW INNODB STATUS中顯式多少個鎖信息
innodb_show_verbose_locks
² 0/1,是否在SHOW INNODB STATUS中顯式更多鎖相關的信息
log_slow_filter
² slowlog過濾器,哪些類型的slowlog不記錄
log_slow_rate_limit
² 1 ~ 1000,和log_slow_rate_type結合起來用。記錄每 1/N次slowlog,不全記錄
log_slow_rate_type
² slowlog控制範圍是每個session,還是每個query。如果是每個session,需要註意連接池情況下無法生效,並且對復制線程也不生效
log_slow_sp_statements
² 是否記錄存儲過程產生的slowlog
log_slow_verbosity
² 設置slowlog中,哪些類型的信息要被記錄下來,一般設置為full
max_binlog_files
² 至多保留多少個binlog文件
slow_query_log_timestamp_always
² 每次slowlog中,是否總是記錄時間戳
thread_statistics
userstat
² 和thread_statistics一起,設置是否統計每個user和thread的信息,存儲在information_schema的幾個表中

CLIENT_STATISTICS
INDEX_STATISTICS
TABLE_STATISTICS
THREAD_STATISTICS
USER_STATISTICS
slow_query_log_timestamp_precision
slow_query_log_use_global_control
Innodb_deadlocks
Innodb_max_trx_id
Innodb_purge_trx_id
Innodb_s_lock_os_waits
Innodb_s_lock_spin_rounds
Innodb_s_lock_spin_waits
Innodb_x_lock_os_waits
Innodb_x_lock_spin_rounds
Innodb_x_lock_spin_waits

【重要】如果需要TokuDB,那麽建議它和MariaDB組合使用

mysql 優化(3)