背景
有張記錄表包含三千多萬條歷史記錄,其中有一半以上數(shù)據(jù)為0,為0數(shù)據(jù)在業(yè)務(wù)上沒有意義,其它表關(guān)聯(lián)此表進(jìn)行統(tǒng)計(jì)查詢較多,為提高查詢效率,故刪除此部分無效數(shù)據(jù)。
方案
因?yàn)橐獎h除一千五百多萬條數(shù)據(jù),直接通過條件進(jìn)行刪除耗時(shí)較長,且易導(dǎo)致鎖表。因此,需要更精細(xì)一點(diǎn)的刪除。
步驟
1、篩選記錄
首先,根據(jù)刪除條件篩選需要刪除的記錄的id
篩選語句:
select id from tablexxx where virtual_flow = 0 and virtual_voice = 0 and flow_date < '2021-04-28 00:00:00'
將篩選出的記錄id全部寫入文件deleteids
mysql -D kyhl -e "$上面篩選語句" > deleteids
檢查一下看有多少條記錄
wc -l deleteids

這里要刪除第一行的列字段
sed '1,1d' deleteids
2、拆分文件
因?yàn)槲募?,先拆分為多個(gè)小文件,按500行一個(gè)文件進(jìn)行拆分
split -l 500 -d --verbose deleteids /root/delete/delete
3、生成sql腳本
寫腳本generateSql.sh,根據(jù)每個(gè)小文件生成刪除語句,就是拼接為刪除的sql,格式為delete from table where id in (id列表)
如下
sed "s/^/'&/g" $1 | sed "s/$/&',/g" | sed '1,1s/^/delete from tbl_card_day_flow where id in (&/g' | sed '$s/,/)/g'
每行前加'
sed 's/^/'&/g' delete00
每行末加',
sed 's/$/&',/g' delete00
首行前加delete from tbl_card_day_flow where iccid_mark in (
sed '1,1s/^/delete from tbl_card_day_flow where iccid_mark in (&/g' delete00
尾行后替換,為)
sed '$s/,/)/g' delete00
4、執(zhí)行腳本
寫腳本circleDelete.sh,遍歷拆分文件目錄,執(zhí)行完一個(gè)就刪除一個(gè)拆分文件
for file in `ls /root/delete`; do
#保存臨時(shí)sql
sql1=`sh /root/generateSql.sh $file > /root/tem_delete.sql`
#執(zhí)行刪除
result=`mysql -D kyhl -e "source /root/tem_delete.sql"`
#結(jié)果保存到文件
echo $result >> /root/tem_delete_result
#刪除拆分文件
rm -f "/root/delete/$file"
#提示
echo "$file執(zhí)行成功"
#休眠1秒再進(jìn)行下次刪除
sleep 1
done
#執(zhí)行
sh circleDelete.sh
踩坑:不應(yīng)該對每個(gè)拆分文件刪除第一行,只需要對總文件刪除第一行即可。