Mysql大表加索引

最近大后臺查看一些數據統計的時候,很慢,甚至會有超時情況,前端設置的超時時間是20秒。
后來通過查看日志和慢查詢,發現一條sql語句執行時間超過18秒,基本都19秒左右。

大表加索引

select (*) from tb_name where create_time > xxx;
最終得知是因為這個表數據行數已經超過 一千萬了,然后create_time字段又沒有索引 。

那解決辦法肯定是加索引嘍。

但是這個表是一直在線上運行,很重要和業務部分。如果給千萬級的大表在線加索引 ,肯定會卡死。

然后就搜羅了一大筐解決方案,比如 在線無鎖加索引使用

ALTER TABLE tbl_name ADD PRIMARY (column), ALGORITHM=INPLACE, LOCK=NONE;
后來才發現,這個特性是Mysql 5.6以后才支持,然而我們的mysql用的是5.5版本

最后在 《高性能Mysql》一書中看到,可在通過 “影子拷貝”來解決,

就是 先創建一張和源表無關的新表,然后通過重命名和刪表操作交換兩張表;

#操作步驟:
#1、創建一張和原表結構一樣的空表,只是表名不一樣
    create table tb_name_tmp like tb_name;

#2、把新建的空表非主鍵索引都刪掉,因為這樣在往新表導數據的時候效率會很快(因為除了必要的主鍵以外,不用再去建立其它索引數據了)
    alter tb_name_tmp drop index index_name;

#3、從舊表往主表里導數據,如果數據太大,建議分批導入,只需確保無重復數據就行,因為導入數據太大,會很占用資源(內存,磁盤io, cpu等),可能會影響舊表在線上的業務。我是每批次100萬條數據導入,基本上每次都是在 20s左右
    insert into tb_name_tmp select * from tb_name where id between start_id and end_id;

#4、數據導完后,再對新表進行添加索引
     create index index_name on tb_name_tmp(column_name);

#5、當大部分數據導入后,索引也建立好了,但是舊表數據量還是會因業務的增長而增長,這時候為了確保新舊表的數據一至性和平滑切換,建議寫一個腳本,判斷當舊表的數據行數與新表一致時,就切換。我是以 max(id)來判斷的。
     table tb_name to tb_name_tmp1;
     table tb_name_tmp to tb_name;

當給新表加完索引后,最上面那條查詢直接就是0.0002s

加索引卡死

場景:在給一張有幾萬條記錄的表添加索引時,進度非常慢,導致其它查詢無法進行

處理方式:
使用Navicat的命令行模式,執行以下命令:

show processlist;
這時會看到有哪些線程正在執行,也可以查看鎖表的線程。你會發現alter table * add key ****那個線程狀態是Waiting for table metadata lock,后面有個這個表的所有操作都是這個狀態,很明顯是這條加索引的語句把表給鎖了。
查看線程ID,執行

kill 線程ID
這樣被鎖住的表就能立即被使用了。

由此得出一個結論,當一張表數據量很大時,不要輕易添加索引,會導致表被鎖死!如果非要添加,那么應該先把數據表進行備份,然后進行空表添加索引。

Mysql online DDL 線上無鎖添加索引

只能通過ALTER TABLE不能create index

ALTER TABLE tbl_name ADD PRIMARY KEY (column), ALGORITHM=INPLACE, LOCK=NONE;

參數說明:

ALGORITHM=INPLACE
更優秀的解決方案,在當前表加索引,步驟:
1.創建索引(二級索引)數據字典
2.加共享表鎖,禁止DML,允許查詢
3.讀取聚簇索引,構造新的索引項,排序并插
入新索引
4.等待打開當前表的所有只讀事務提交
5.創建索引結束
 
ALGORITHM=COPY
通過臨時表創建索引,需要多一倍存儲,還有更多的IO,步驟:
1.新建帶索引(主鍵索引)的臨時表
2.鎖原表,禁止DML,允許查詢
3.將原表數據拷貝到臨時表
4.禁止讀寫,進行rename,升級字典鎖
5.完成創建索引操作
 
LOCK=DEFAULT:默認方式,MySQL自行判斷使用哪種LOCK模式,盡量不鎖表
LOCK=NONE:無鎖:允許Online DDL期間進行并發讀寫操作。如果Online DDL操
作不支持對表的繼續寫入,則DDL操作失敗,對表修改無效
LOCK=SHARED:共享鎖:Online DDL操作期間堵塞寫入,不影響讀取
LOCK=EXCLUSIVE:排它鎖:Online DDL操作期間不允許對鎖表進行任何操作

給1E數據庫在線加索引

數據庫在線加索引
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MySQL connection id is 7995759
Server version: 5.7.25-log Source distribution
 
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
 
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
 
MySQL [(none)]> use sdorica_exp
 
MySQL [sdorica_exp]> show index from gashapon_outcome_records;
Empty set (0.00 sec)
 
MySQL [sdorica_exp]> select count(1) from gashapon_outcome_records;
+-----------+
| count(1)  |
+-----------+
| 111579926 |
+-----------+
1 row in set (1 min 10.13 sec)
 
MySQL [sdorica_exp]> ALTER TABLE gashapon_outcome_records ADD INDEX idx_roll_gashapon_record_id (roll_gashapon_record_id) , ALGORITHM=INPLACE, LOCK=NONE;
 
 
Query OK, 0 rows affected (15 min 34.16 sec)
Records: 0  Duplicates: 0  Warnings: 0
 
 
MySQL [sdorica_exp]> show index from gashapon_outcome_records;
+--------------------------+------------+-----------------------------+--------------+-------------------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table                    | Non_unique | Key_name                    | Seq_in_index | Column_name             | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+--------------------------+------------+-----------------------------+--------------+-------------------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| gashapon_outcome_records |          1 | idx_roll_gashapon_record_id |            1 | roll_gashapon_record_id | A         |    51825872 |     NULL | NULL   | YES  | BTREE      |         |               |
+--------------------------+------------+-----------------------------+--------------+-------------------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
1 row in set (0.01 sec)
 
MySQL [sdorica_exp]> 
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容