mysql delete operation is actually false deleted

Copyright: Original article reproduced please indicate the source. https://blog.csdn.net/samll_snail/article/details/90370201

In InnoDB, you delete operation, not actually delete the data, mysql is really just to delete the data called mark, marked for deletion, so you use the Data Delete to delete the table, the table files on disk small footprint will not change, we are here let us call it false deleted .

 

This is the conclusion above, we can verify the next through an example.

 

Follow the example of the previous article it, first create a stored procedure, the insertion of data 10w, 10w of data and then look at this accounts for much space.

 

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),'M') from tables where table_schema='test' AND table_name='t';
+-------------------------------------------------+
| concat(round(sum(DATA_LENGTH/1024/1024),2),'M') |
+-------------------------------------------------+
| 3.52M                                           |
+-------------------------------------------------+
1 row in set (0.04 sec)

 

10w can see pieces of data in mysql occupies a space the size of 3.52M, then we delete command delete from t, then look at it.

 

#先删除表所有数据,再重新查看表文件大小
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),'M') from tables where table_schema='test' AND table_name='t';
+-------------------------------------------------+
| concat(round(sum(DATA_LENGTH/1024/1024),2),'M') |
+-------------------------------------------------+
| 3.52M                                           |
+-------------------------------------------------+
1 row in set (0.00 sec)

 

From the results can be found in the data table is cleared, the table does not change the amount of space, which verified the above conclusions, delete operation does not really delete data table space has not been released.

 

These rows are deleted, but is marked for deletion, can be reused, the next time there are matching records can be inserted directly into the marked location.

 

For example, we delete a record id id = 500 in between 300-600 record, this record will be marked for deletion, if there is a record of a id = 400 to be inserted in, then you can re-inferior with id = 500 positions are marked for deletion, this is called rows reuse .

 

Another is that the data page reuse , refers to the entire data pages are marked for deletion, so that the entire data page can be re-used, and rows of different multiplexing is multiplexed on the data page to be inserted data is almost no conditions.

 

Also to the insertion of the above example, if you want to insert the record id = 1000, then it can not be reused id = 500 in this position, but if there's a whole page of data can be reused, then no matter id how much value can be multiplexed on this page.

 

These are marked deleted records, in fact, a hollow, a kind of feeling of the dog in the manger, is not that a waste of space, but also affect query efficiency.

 

Because, you know, mysql underlying data is stored in units of pages and read data, each read data to a disk in a data page is read, but every page you visit a data corresponding to a disk IO operations, disk IO the relative memory access speed is very slow.

 

So you think, if there is a large amount of data voids, originally just a data page on the data stored on the table, due to the space occupied by empty lot and had to add other data pages need to save the data, corresponding, mysql when the query the same data, you have to increase disk IO operations, thus affecting the query speed.

 

In fact, not only can cause data deletion hole, insert and update will also cause voids will not elaborate here, you know on the line.

 

Therefore, a data table after a large number of frequent additions and deletions will inevitably produce data empty, wasted space and affect query efficiency, usually manifested in a production environment directly to the original query soon becomes slower and slower.

 

In this case, we can usually use the following command will be able to solve the problem of empty data.

 

optimize table t

 

This principle of command is to rebuild the table, all the data is to create a temporary table B, then table A (there is data empty table) query out, and then re-insert all the data into a temporary table B, then the final temporary table B to a substitution table, which is the process of rebuilding the table.

 

Let's try it and see results.

 

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),'M') from tables where table_schema='test' AND table_name='t';
+-------------------------------------------------+
| concat(round(sum(DATA_LENGTH/1024/1024),2),'M') |
+-------------------------------------------------+
| 0.02M                                           |
+-------------------------------------------------+
1 row in set (0.00 sec)

 

See table file size has become 0.02M, indicating table space is freed up, this should be 0.02M define the size of the file table structure.

 

In addition the following command to rebuild the table can also be achieved, with the above can achieve the same effect, and we recommend using this command, you can try.

 

alter table t engine=InnoDB

 

Note that this article is based on the InnoDB engine, there may be some differences for the other engines. The original is not easy, if the article has inspired you, you point a praise it, there are questions can exchange messages below, you can also communicate with my private letter, thanks for the support.

Guess you like

Origin blog.csdn.net/samll_snail/article/details/90370201