目錄
mysql刪除操作其實是假刪除
我們可以透過一個例子來驗證下
看看效果
首頁 資料庫 mysql教程 mysql刪除操作其實是假刪除問題怎麼解決

mysql刪除操作其實是假刪除問題怎麼解決

May 30, 2023 pm 01:22 PM
mysql

mysql刪除操作其實是假刪除

在InnoDB 中,你的delete 操作,並不會真的把資料刪除,mysql 其實只是給刪除的資料打了個標記,標記為刪除,因此你使用delete 刪除表中的數據,表檔案在磁碟上所佔空間不會變小,我們這裡暫且稱之為假刪除

我們可以透過一個例子來驗證下

沿用前面文章中的例子吧,先創建一個存儲過程,插入10w 條數據,然後看下這10w 條數據佔了多大的空間。

CREATE TABLE `t` (
  `id` int(11) NOT NULL,
  `a` int(11) DEFAULT NULL,
  `b` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `a` (`a`),
  KEY `b` (`b`)
) ENGINE=InnoDB;
登入後複製
#定义分割符号,mysql 默认分割符为分号;,这里定义为 //
#分隔符的作用主要是告诉mysql遇到下一个 // 符号即执行上面这一整段sql语句
delimiter //
 
#创建一个存储过程,并命名为 testData
create procedure testData() 
 
#下面这段就是表示循环往表里插入10w条数据
begin
  declare i int;
  set i=1;
  while(i<=100000)do
    insert into t values(i, i, i);
    set i=i+1;
  end while;
end //  #这里遇到//符号,即执行上面一整段sql语句
 
delimiter ; #恢复mysql分隔符为;
 
call testData(); #调用存储过程
登入後複製
#下面这两条命令可以查看表文件所占空间大小
mysql> use information_schema;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
 
Database changed
mysql> select concat(round(sum(DATA_LENGTH/1024/1024),2),&#39;M&#39;) from tables where table_schema=&#39;test&#39; AND table_name=&#39;t&#39;;
+-------------------------------------------------+
| concat(round(sum(DATA_LENGTH/1024/1024),2),&#39;M&#39;) |
+-------------------------------------------------+
| 3.52M                                           |
+-------------------------------------------------+
1 row in set (0.04 sec)
登入後複製

可以看到 10w 資料在 mysql 中佔用了 3.52M 大小的空間,那麼我們執行刪除指令 delete from t,再看看呢。

#先删除表所有数据,再重新查看表文件大小
mysql> delete from t;
Query OK, 100000 rows affected (0.46 sec)
 
mysql> use information_schema;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
 
Database changed
mysql> select concat(round(sum(DATA_LENGTH/1024/1024),2),&#39;M&#39;) from tables where table_schema=&#39;test&#39; AND table_name=&#39;t&#39;;
+-------------------------------------------------+
| concat(round(sum(DATA_LENGTH/1024/1024),2),&#39;M&#39;) |
+-------------------------------------------------+
| 3.52M                                           |
+-------------------------------------------------+
1 row in set (0.00 sec)
登入後複製

從結果可以發現表數據被清空後,表所佔空間大小並沒有變化,這就驗證了上面的結論,delete 操作並沒有真正刪除數據,表的空間並沒有被釋放。

這些被刪除的記錄行,只是被標記刪除,是可以被重複使用的,下次有符合條件的記錄是可以直接插入到這個被標記的位置的。

例如我們在id 為300-600 之間的記錄中刪除一筆id=500 的記錄,這條記錄就會被標記為刪除,等下次如果有一筆id=400 的記錄要插入進來,那麼就可以重複用id=500 被標記刪除的位置,這種情況叫做行記錄複用

還有一種情況是資料頁複用,就是指整個資料頁都被標記刪除了,於是這整個資料頁都可以被複用了,和行記錄復用不同的是,資料頁復用對要插入的資料幾乎沒有條件限制。

還以上面那個插入為例,假如要插入的記錄是id=1000,那麼就不能復用id=500 這個位置了,但如果有一整個數據頁可復用的話,那麼無論id值為多少都可以重複使用在這個頁上。

這些被標記刪除的記錄,其實就是一個空洞,有種佔著茅坑不拉屎的感覺,浪費空間不說,還會影響查詢效率。

因為你要知道,mysql 在底層是以資料頁為單位來儲存和讀取資料的,每次向磁碟讀一次資料就是讀一個資料頁,然而每存取一個資料頁就對應一次磁碟IO 操作,磁碟IO 相對記憶體存取速度是相當慢的。

所以你想想,如果一個表上存在大量的數據空洞,原本只需一個數據頁就保存的數據,由於被很多空洞佔用了空間,不得不需要增加其他的數據頁來保存數據,相應的,mysql 在查詢相同數據的時候,就不得不增加磁碟IO 操作,從而影響查詢速度。

其實不只是刪除操作會造成資料空洞,插入和更新同樣也會造成空洞,這裡就不細說了,你知道就行。

因此,一個資料表在經過大量頻繁的增刪改之後,難免會產生資料空洞,浪費空間並影響查詢效率,通常在生產環境中會直接表現為原本很快的查詢會變得越來越慢。

對於這種情況,我們通常可以使用下面這個指令就能解決資料空洞問題。

optimize table t
登入後複製

這個指令的原理就是重建表,就是建立一個臨時表B,然後把表A(存在資料空洞的表) 中的所有資料查詢出來,接著把資料全部重新插入到臨時表B中,最後再用臨時表B 取代表A 即可,這就是重建表的過程。

我們再來試驗一下。

看看效果

mysql> optimize table t;
+--------+----------+----------+-------------------------------------------------------------------+
| Table  | Op       | Msg_type | Msg_text                                                          |
+--------+----------+----------+-------------------------------------------------------------------+
| test.t | optimize | note     | Table does not support optimize, doing recreate + analyze instead |
| test.t | optimize | status   | OK                                                                |
+--------+----------+----------+-------------------------------------------------------------------+
2 rows in set (0.39 sec)
 
mysql> use information_schema;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
 
Database changed
mysql> select concat(round(sum(DATA_LENGTH/1024/1024),2),&#39;M&#39;) from tables where table_schema=&#39;test&#39; AND table_name=&#39;t&#39;;
+-------------------------------------------------+
| concat(round(sum(DATA_LENGTH/1024/1024),2),&#39;M&#39;) |
+-------------------------------------------------+
| 0.02M                                           |
+-------------------------------------------------+
1 row in set (0.00 sec)
登入後複製

可以看到表格檔案大小變成 0.02M了,表示表空間被釋放了,這個 0.02M 應該是定義表結構檔案的大小了。

另外下面這個指令也可以實現重建表,可以達到跟上面一樣的效果,而且推薦大家使用下面這個指令,大家可以試試看。

alter table t engine=InnoDB
登入後複製

注意本文內容是基於 InnoDB 引擎,對於其他引擎可能會有一些差異。

以上是mysql刪除操作其實是假刪除問題怎麼解決的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

<🎜>:泡泡膠模擬器無窮大 - 如何獲取和使用皇家鑰匙
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系統,解釋
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
Mandragora:巫婆樹的耳語 - 如何解鎖抓鉤
3 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1665
14
CakePHP 教程
1423
52
Laravel 教程
1321
25
PHP教程
1269
29
C# 教程
1249
24
laravel入門實例 laravel入門實例 Apr 18, 2025 pm 12:45 PM

Laravel 是一款 PHP 框架,用於輕鬆構建 Web 應用程序。它提供一系列強大的功能,包括:安裝: 使用 Composer 全局安裝 Laravel CLI,並在項目目錄中創建應用程序。路由: 在 routes/web.php 中定義 URL 和處理函數之間的關係。視圖: 在 resources/views 中創建視圖以呈現應用程序的界面。數據庫集成: 提供與 MySQL 等數據庫的開箱即用集成,並使用遷移來創建和修改表。模型和控制器: 模型表示數據庫實體,控制器處理 HTTP 請求。

MySQL和PhpMyAdmin:核心功能和功能 MySQL和PhpMyAdmin:核心功能和功能 Apr 22, 2025 am 12:12 AM

MySQL和phpMyAdmin是強大的數據庫管理工具。 1)MySQL用於創建數據庫和表、執行DML和SQL查詢。 2)phpMyAdmin提供直觀界面進行數據庫管理、表結構管理、數據操作和用戶權限管理。

MySQL與其他編程語言:一種比較 MySQL與其他編程語言:一種比較 Apr 19, 2025 am 12:22 AM

MySQL与其他编程语言相比,主要用于存储和管理数据,而其他语言如Python、Java、C 则用于逻辑处理和应用开发。MySQL以其高性能、可扩展性和跨平台支持著称,适合数据管理需求,而其他语言在各自领域如数据分析、企业应用和系统编程中各有优势。

解決數據庫連接問題:使用minii/db庫的實際案例 解決數據庫連接問題:使用minii/db庫的實際案例 Apr 18, 2025 am 07:09 AM

在開發一個小型應用時,我遇到了一個棘手的問題:需要快速集成一個輕量級的數據庫操作庫。嘗試了多個庫後,我發現它們要么功能過多,要么兼容性不佳。最終,我找到了minii/db,這是一個基於Yii2的簡化版本,完美地解決了我的問題。

laravel框架安裝方法 laravel框架安裝方法 Apr 18, 2025 pm 12:54 PM

文章摘要:本文提供了詳細分步說明,指導讀者如何輕鬆安裝 Laravel 框架。 Laravel 是一個功能強大的 PHP 框架,它 упростил 和加快了 web 應用程序的開發過程。本教程涵蓋了從系統要求到配置數據庫和設置路由等各個方面的安裝過程。通過遵循這些步驟,讀者可以快速高效地為他們的 Laravel 項目打下堅實的基礎。

解決MySQL模式問題:TheliaMySQLModesChecker模塊的使用體驗 解決MySQL模式問題:TheliaMySQLModesChecker模塊的使用體驗 Apr 18, 2025 am 08:42 AM

在使用Thelia開發電商網站時,我遇到了一個棘手的問題:MySQL模式設置不當,導致某些功能無法正常運行。經過一番探索,我找到了一個名為TheliaMySQLModesChecker的模塊,它能夠自動修復Thelia所需的MySQL模式,徹底解決了我的困擾。

MySQL:結構化數據和關係數據庫 MySQL:結構化數據和關係數據庫 Apr 18, 2025 am 12:22 AM

MySQL通過表結構和SQL查詢高效管理結構化數據,並通過外鍵實現表間關係。 1.創建表時定義數據格式和類型。 2.使用外鍵建立表間關係。 3.通過索引和查詢優化提高性能。 4.定期備份和監控數據庫確保數據安全和性能優化。

MySQL:解釋的關鍵功能和功能 MySQL:解釋的關鍵功能和功能 Apr 18, 2025 am 12:17 AM

MySQL是一個開源的關係型數據庫管理系統,廣泛應用於Web開發。它的關鍵特性包括:1.支持多種存儲引擎,如InnoDB和MyISAM,適用於不同場景;2.提供主從復制功能,利於負載均衡和數據備份;3.通過查詢優化和索引使用提高查詢效率。

See all articles