物流規則匹配日誌表記錄訂單匹配規則相關日誌信息,方便管理員維護和查閱不匹配的訂單,四個月時間,該日誌表數據就有174G,當前,這麼大的數據量,不只對數據庫形成了很大的負載壓力,同時查詢等維護也緩慢,因此採起將日誌記錄移出到文件進行存儲。可是短時間內,還須要數據庫中的部分日誌記錄,故而有了下面的刪除記錄、優化表操做。php
表自己有六七百萬條數據,從六七百萬刪到五百多萬,發現數據佔用空間大小一點也沒變,以下圖所示。網上查到須要釋放刪除了的數據佔用的空間、也就是優化表或碎片整理,使用到的命令是:
OPTIMIZE TABLE tableName
。html
在刪除sql語句中,寫法以下:DELETE FROM ueb_logistics_rule_logs
WHERE type=0 LIMIT 100; 凡是這樣,delete帶有where條件的,都不是真刪除,只是MySQL給記錄加了個刪除標識,天然這樣操做後表數據佔有空間也不會變小了mysql
注意:DELETE FROM
ueb_logistics_rule_logs
; 這條sql語句執行後,就清空了表數據,佔有空間就變爲0了linux
主要就是執行下面三條sql語句(輪詢刪除delete,避免一次性刪除數據太多形成MySQL負載崩潰,另外數據量大的時候須要等待網站訪問流量小的時候執行)sql
ueb_logistics_rule_logs
WHERE type=0 LIMIT 100;ueb_logistics_rule_logs
;基於yii1版本框架,命令行下執行,能夠加入定時腳本任務裏,自動執行數據庫
<?php /** * 定時清理相關表數據 * Class Logisticstable */ class LogisticstableCommand extends CConsoleCommand { public $before15Days; public $oneMonthAgo; public $halfYearAgo; /** * 清理表數據 * * windows環境: * >yiic.bat Logisticstable Execute * >yiic.bat Logisticstable Execute 10 * linux環境: * >./yiic Logisticstable Execute * >./yiic Logisticstable Execute 10 * * @param int $limit 清理的條數 */ public function actionExecute($limit = 100) { $sTime = microtime(true); $this->initDaytime(); $dbList = $this->tableData(); $cacheKey = 'command:logisticstable:%s:%s'; foreach ($dbList as $db=>$tableList){ foreach ($tableList as $tableInfo){ $tableName = $tableInfo['tableName']; $cacheKeyTmp = sprintf($cacheKey, $db, $tableName); $isRunning = Redis::getCache($cacheKeyTmp); if (!empty($isRunning)){ //當前表正在清理中…… continue; } Redis::setCache($cacheKeyTmp, 1, 36000); //輪詢刪除表數據 while(!$this->myDeleteData($db, $tableName, $tableInfo['whereStr'], $limit)){ sleep(3); } //優化表空間 $this->myOptimizeTable($db, $tableName); Redis::deleteCache($cacheKeyTmp); sleep(10); } } echo '共計耗時:'. (microtime(true)-$sTime).' s'.PHP_EOL; exit(0); } /** * 刪除表數據 * @param $db * @param $tableName * @param $where * @param int $limit * @return bool */ protected function myDeleteData($db, $tableName, $where, $limit = 1000) { //鏈接數據庫 $connection = Yii::app()->$db; $findSql = "SELECT * FROM `".$tableName."` WHERE $where "; $arrRow = $connection->createCommand($findSql)->queryRow(); if (empty($arrRow)){ //沒有要刪除的數據了 return true; } //刪除 $deleteSql = "DELETE FROM `".$tableName."` WHERE $where LIMIT $limit "; $connection->createCommand($deleteSql)->execute(); return false; } /** * 釋放被刪除數據佔用的空間 * @param $db * @param $tableName * @return mixed */ protected function myOptimizeTable($db, $tableName) { //鏈接數據庫 $connection = Yii::app()->$db; //優化表空間 $optimizeSql = "OPTIMIZE TABLE `".$tableName."`"; return $connection->createCommand($optimizeSql)->execute(); } /** * 初始化時間 */ protected function initDaytime() { $this->before15Days = date('Y-m-d H:i:s', strtotime('-15 day')); $this->oneMonthAgo = date('Y-m-d H:i:s', strtotime('-1 month')); $this->halfYearAgo = date('Y-m-d H:i:s', strtotime('-6 month')); } /** * 相關表數據 */ protected function tableData() { return [ 'db_logistics'=>[ [ //check_task_is_run 保留最新15天 'tableName'=>'check_task_is_run', 'whereStr'=> "create_time < '{$this->before15Days}'" ], [ //check_task_run_get_logistict_cost 30天 'tableName'=>'check_task_run_get_logistict_cost', 'whereStr'=> "create_time < '{$this->oneMonthAgo}'" ], [ //ueb_logistics_rule_opration_log 半年 'tableName'=>'ueb_logistics_rule_opration_log', 'whereStr'=> "create_time < '{$this->before15Days}'" ], ] ]; } }
慚愧,今天才碰到這類問題,MySQL delete表數據,以前一直的感受就是直接刪除掉了,數據所佔的空間也天然會釋放,可是今天才發現,delete sql語句後加where條件刪除的數據MySQL會自動加個delete標識而不會真的刪掉。學的太淺了,還需多多努力!windows