索引實踐和調優(1)

Ⅰ、如何使用B+ tree索引

(root@localhost) [test]> desc l;
+-------+---------+------+-----+---------+-------+
| Field | Type    | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| a     | int(11) | NO   | PRI | NULL    |       |
| b     | int(11) | YES  | MUL | NULL    |       |
| c     | int(11) | YES  | UNI | NULL    |       |
| d     | int(11) | YES  |     | NULL    |       |
+-------+---------+------+-----+---------+-------+
4 rows in set (0.00 sec)

(root@localhost) [test]> explain select b from l where c = 10;
+----+-------------+-------+------------+-------+---------------+------+---------+-------+------+----------+-------+
| id | select_type | table | partitions | type  | possible_keys | key  | key_len | ref   | rows | filtered | Extra |
+----+-------------+-------+------------+-------+---------------+------+---------+-------+------+----------+-------+
|  1 | SIMPLE      | l     | NULL       | const | c             | c    | 5       | const |    1 |   100.00 | NULL  |
+----+-------------+-------+------------+-------+---------------+------+---------+-------+------+----------+-------+
1 row in set, 1 warning (0.00 sec)

(root@localhost) [test]> explain select b from l where d = 10;
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra       |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | l     | NULL       | ALL  | NULL          | NULL | NULL    | NULL |    4 |    25.00 | Using where |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.01 sec)

看key值,表示這條sql語句的執行計劃使用了哪個索引,沒走索引,key值就是NULL,這時候就會掃描所有數據mysql

線上刪除索引不須要在線工具,只是將索引所佔的空間釋放掉,很快,不須要pt-oscgit

alter table orders drop index xxx

Ⅱ、線上調優

大部分都是看慢查詢日誌,找到慢sql,複製出來去命令行裏explain一把,看下具體狀況,缺乏索引就加一下,一百五十萬數據的一張表加一個索引差很少要4sgithub

線上的slow-log好幾個g,怎麼看?sql

mysqldumpslow slow.log |less,這樣會把對一些表的操做格式化
-s [option]
    c    l    r    t
    at(average query time) 執行時間倒敘     默認
-r 逆序
-t 3 看top3

這個工具會解析全部slow.log 量太大,解析依然很慢,這時候就須要用到採樣數據庫

tail -n 10000 slow.log > analytics.log
mysqldumpslow analytics.log

tips:如何在線清理慢日誌?less

直接 > slow.log 這樣是不行的,由於mysql對應這個文件的句柄依然打開,磁盤空間釋放不出來的,工具

正確作法,先備份,mv slow.log slow.lg.170302,雖然更名,但句柄未變,此時慢日誌仍是會往裏面寫,命令行

在數據庫中flush slow logs 一把,此時纔會關閉以前的慢查詢日誌的句柄,從新打開一個新慢日誌的句柄日誌

Ⅲ、5.7中分析慢sql利器

sys庫中一個表
statement_analysis表,這個看起來比slow.log看起來更直觀,這個表很是重要,這個表不會很大,有參數來控制它最大多少行,後面再講
x$statement_analysis 這樣查,就不會把表裏的時間什麼的格式化,全是數字,若是想對這張表進行每秒鐘採集,將這些數值作差值,能夠獲得某個波段的增加量code

(root@localhost) [sys]> show create table statement_analysis\G
*************************** 1. row ***************************
                View: statement_analysis
         Create View: CREATE ALGORITHM=MERGE DEFINER=`mysql.sys`@`localhost` SQL SECURITY INVOKER VIEW `statement_analysis` AS select `sys`.`format_statement`(`performance_schema`.`events_statements_summary_by_digest`.`DIGEST_TEXT`) AS `query`,`performance_schema`.`events_statements_summary_by_digest`.`SCHEMA_NAME` AS `db`,if(((`performance_schema`.`events_statements_summary_by_digest`.`SUM_NO_GOOD_INDEX_USED` > 0) or (`performance_schema`.`events_statements_summary_by_digest`.`SUM_NO_INDEX_USED` > 0)),'*','') AS `full_scan`,`performance_schema`.`events_statements_summary_by_digest`.`COUNT_STAR` AS `exec_count`,`performance_schema`.`events_statements_summary_by_digest`.`SUM_ERRORS` AS `err_count`,`performance_schema`.`events_statements_summary_by_digest`.`SUM_WARNINGS` AS `warn_count`,`sys`.`format_time`(`performance_schema`.`events_statements_summary_by_digest`.`SUM_TIMER_WAIT`) AS `total_latency`,`sys`.`format_time`(`performance_schema`.`events_statements_summary_by_digest`.`MAX_TIMER_WAIT`) AS `max_latency`,`sys`.`format_time`(`performance_schema`.`events_statements_summary_by_digest`.`AVG_TIMER_WAIT`) AS `avg_latency`,`sys`.`format_time`(`performance_schema`.`events_statements_summary_by_digest`.`SUM_LOCK_TIME`) AS `lock_latency`,`performance_schema`.`events_statements_summary_by_digest`.`SUM_ROWS_SENT` AS `rows_sent`,round(ifnull((`performance_schema`.`events_statements_summary_by_digest`.`SUM_ROWS_SENT` / nullif(`performance_schema`.`events_statements_summary_by_digest`.`COUNT_STAR`,0)),0),0) AS `rows_sent_avg`,`performance_schema`.`events_statements_summary_by_digest`.`SUM_ROWS_EXAMINED` AS `rows_examined`,round(ifnull((`performance_schema`.`events_statements_summary_by_digest`.`SUM_ROWS_EXAMINED` / nullif(`performance_schema`.`events_statements_summary_by_digest`.`COUNT_STAR`,0)),0),0) AS `rows_examined_avg`,`performance_schema`.`events_statements_summary_by_digest`.`SUM_ROWS_AFFECTED` AS `rows_affected`,round(ifnull((`performance_schema`.`events_statements_summary_by_digest`.`SUM_ROWS_AFFECTED` / nullif(`performance_schema`.`events_statements_summary_by_digest`.`COUNT_STAR`,0)),0),0) AS `rows_affected_avg`,`performance_schema`.`events_statements_summary_by_digest`.`SUM_CREATED_TMP_TABLES` AS `tmp_tables`,`performance_schema`.`events_statements_summary_by_digest`.`SUM_CREATED_TMP_DISK_TABLES` AS `tmp_disk_tables`,`performance_schema`.`events_statements_summary_by_digest`.`SUM_SORT_ROWS` AS `rows_sorted`,`performance_schema`.`events_statements_summary_by_digest`.`SUM_SORT_MERGE_PASSES` AS `sort_merge_passes`,`performance_schema`.`events_statements_summary_by_digest`.`DIGEST` AS `digest`,`performance_schema`.`events_statements_summary_by_digest`.`FIRST_SEEN` AS `first_seen`,`performance_schema`.`events_statements_summary_by_digest`.`LAST_SEEN` AS `last_seen` from `performance_schema`.`events_statements_summary_by_digest` order by `performance_schema`.`events_statements_summary_by_digest`.`SUM_TIMER_WAIT` desc
character_set_client: utf8
collation_connection: utf8_general_ci
1 row in set (0.00 sec)

會發現是一張視圖,數據是從performance_schema庫中的events_statements_summary_by_digest中抽取的,而且這張表自己就根據總的等待時間排序了,這東西方便後續作awr之類的工具

tips:
sys庫中,全部的表都是視圖,用於方便統計,以前須要去performance_schema中看events_statements_summary_by_digest

statements_with_errors_or_warnings        執行後有錯或者報警的
statements_with_full_table_scans          沒有走索引也就是全表掃描
statements_with_sorting                   帶有排序的
statements_with_temp_tables               帶有臨時表的

找線上哪些sql平均慢了看sys庫,哪一個時間點慢了看slow.log

5.6怎麼辦,沒sys庫
本身建立sys庫

cd /tmp
git clone https://github.com/mysql/mysql-sys
cd mysql-sys/
mysql -u root -p < ./sys_56.sql

貌似表比5.7要少一點

tips:
這些視圖能夠認爲存內存的,不佔特別大開銷,5.6開始,實際上是須要打開performance_schema參數的,不過是默認打開的
performance_schema庫太專業,不少東西和內核有關,普通用戶不建議看,能看sys庫已經不錯了

Ⅳ、補充

sys庫中還有個表schema_index_statistics能夠查看每一個索引使用狀況,增刪查改全部的次數和時間均可以看到,能知道哪張表的哪一個索引比較活躍

statement_analysis、schema_index_statistics、慢查詢 三個結合起來能夠進行一個初步調優了

相關文章
相關標籤/搜索