mysql數據庫大表加索引


最近大后台查看一些數據統計的時候,很慢,甚至會有超時情況,前端設置的超時時間是20秒。

后來通過查看日志和慢查詢,發現一條sql語句執行時間超過18秒,基本都19秒左右。

 select count(*) from tb_name where create_time > xxx;

最終得知是因為這個表數據行數已經超過 一千萬了,然后create_time字段又沒有索引 。

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

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

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

ALTER TABLE tbl_name ADD PRIMARY KEY (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)來判斷的。
    rename table tb_name to tb_name_tmp1;
    rename table tb_name_tmp to tb_name;

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM