免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2620 | 回复: 5

Memory表,删除数据时的处理 [复制链接]

论坛徽章:
0
发表于 2010-06-06 14:46 |显示全部楼层
本帖最后由 xiao7ng 于 2010-06-06 14:48 编辑

一天同事问我,一处英文手册上的一段话的意思

Space for MEMORY tables is allocated in small blocks. Tables use 100% dynamic hashing for inserts. No overflow area or extra key space is needed. No extra space is needed for free lists. Deleted rows are put in a linked list and are reused when you insert new data into the table. MEMORY tables also have none of the problems commonly associated with deletes plus inserts in hashed tables.

说实话英文比较菜,不过知道大概意思,就是memory表删除数据的时候并不回收内存空间,而是在一个linked list记录那些行被删除,然后新插入的数据,不是添加到末尾,而是插入到那些"空洞"中.为了说服同事,于是我做了如下实验:

同时建立2张表,一张myisam的,一张memory的,结构一致,只是engine不同

CREATE TABLE `mem` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `content` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MEMORY ;

CREATE TABLE `myi` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `content` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MYISAM;

root@localhost[test] 01:34>call insert_table(10000,'mem');
Query OK, 0 rows affected (2.11 sec)

root@localhost[test] 01:35>call insert_table(10000,'myi');
Query OK, 0 rows affected (1.84 sec)

并插入10000条数据,同时查看表状态

root@localhost[test] 01:35>show table status like "mem"\G
*************************** 1. row ***************************
           Name: mem
         Engine: MEMORY
        Version: 10
     Row_format: Fixed
           Rows: 10001
Avg_row_length: 261
   Data_length: 2693200
Max_data_length: 16098480
   Index_length: 99200
      Data_free: 0
Auto_increment: 10002
    Create_time: NULL
    Update_time: NULL
     Check_time: NULL
      Collation: latin1_swedish_ci
       Checksum: NULL
Create_options:
        Comment:
1 row in set (0.00 sec)

root@localhost[test] 01:38>show table status like "myi"\G
*************************** 1. row ***************************
           Name: myi
         Engine: MyISAM
        Version: 10
     Row_format: Dynamic
           Rows: 10001
Avg_row_length: 128
   Data_length: 1280220
Max_data_length: 281474976710655
   Index_length: 105472
      Data_free: 0
Auto_increment: 10002
    Create_time: 2010-06-06 00:46:08
    Update_time: 2010-06-06 01:35:20
     Check_time: NULL
      Collation: latin1_swedish_ci
       Checksum: NULL
Create_options:
        Comment:
1 row in set (0.00 sec)

其实也可以看出,memory比myisam浪费空间,呵呵,这不是这里重点,现在各自删除1000条记录在查看状态

root@localhost[test] 01:38>delete from mem where id between 1000 and 2000;
Query OK, 1001 rows affected (0.00 sec)

root@localhost[test] 01:42>delete from myi where id between 1000 and 2000;
Query OK, 1001 rows affected (0.11 sec)

root@localhost[test] 01:42>show table status like "mem"\G
*************************** 1. row ***************************
           Name: mem
         Engine: MEMORY
        Version: 10
     Row_format: Fixed
           Rows: 9000
Avg_row_length: 261
   Data_length: 2693200
Max_data_length: 16098480
   Index_length: 99200
      Data_free: 261261
Auto_increment: 10002
    Create_time: NULL
    Update_time: NULL
     Check_time: NULL
      Collation: latin1_swedish_ci
       Checksum: NULL
Create_options:
        Comment:
1 row in set (0.00 sec)

root@localhost[test] 01:42>show table status like "myi"\G
*************************** 1. row ***************************
           Name: myi
         Engine: MyISAM
        Version: 10
     Row_format: Dynamic
           Rows: 9000
Avg_row_length: 127
    Data_length: 1280220
Max_data_length: 281474976710655
   Index_length: 105472
      Data_free: 129632
Auto_increment: 10002
    Create_time: 2010-06-06 00:46:08
    Update_time: 2010-06-06 01:42:14
     Check_time: NULL
      Collation: latin1_swedish_ci
       Checksum: NULL
Create_options:
        Comment:
1 row in set (0.00 sec)

除了行数,数据文件大小没有变化,再插入1000条数据,观察状态

root@localhost[test] 01:42>call insert_table(1000,'mem');
Query OK, 0 rows affected (0.30 sec)

root@localhost[test] 01:45>call insert_table(1000,'myi');
Query OK, 0 rows affected (0.45 sec)

root@localhost[test] 01:45>show table status like "mem"\G
*************************** 1. row ***************************
           Name: mem
         Engine: MEMORY
        Version: 10
     Row_format: Fixed
           Rows: 10001
Avg_row_length: 261
    Data_length: 2693200
Max_data_length: 16098480
   Index_length: 99200
      Data_free: 0
Auto_increment: 11003
    Create_time: NULL
    Update_time: NULL
     Check_time: NULL
      Collation: latin1_swedish_ci
       Checksum: NULL
Create_options:
        Comment:
1 row in set (0.00 sec)

root@localhost[test] 01:45>show table status like "myi"\G
*************************** 1. row ***************************
           Name: myi
         Engine: MyISAM
        Version: 10
     Row_format: Dynamic
           Rows: 10001
Avg_row_length: 130
   Data_length: 1302056
Max_data_length: 281474976710655
   Index_length: 105472
      Data_free: 0
Auto_increment: 11003
    Create_time: 2010-06-06 00:46:08
    Update_time: 2010-06-06 01:45:30
     Check_time: NULL
      Collation: latin1_swedish_ci
       Checksum: NULL
Create_options:
        Comment:
1 row in set (0.00 sec)

可以看出myisam表的数据文件变大了,而memory没有,则说明新的数据真的插到那些"空洞"中了.其实想想也不奇怪,因为,如果memory没有这样的机制,在添加,删除频繁的应用场景下是非常浪费内存的.写这个并不是要说明我发现了这么个东西,只是想告诉大家一个方法,这些东西其实非常简单的

论坛徽章:
9
每日论坛发贴之星
日期:2016-01-04 06:20:00数据库技术版块每日发帖之星
日期:2016-01-04 06:20:00每日论坛发贴之星
日期:2016-01-04 06:20:00数据库技术版块每日发帖之星
日期:2016-01-04 06:20:00IT运维版块每日发帖之星
日期:2016-01-04 06:20:00IT运维版块每日发帖之星
日期:2016-01-04 06:20:00综合交流区版块每日发帖之星
日期:2016-01-04 06:20:00综合交流区版块每日发帖之星
日期:2016-01-04 06:20:00数据库技术版块每周发帖之星
日期:2016-03-07 16:30:25
发表于 2010-06-06 19:25 |显示全部楼层
顶技术贴~ MyISAM我比较疑惑,记得也会自动填充的~难道是只有fixed -row -format 才会?
我去查查文档。。。

论坛徽章:
0
发表于 2010-06-07 11:15 |显示全部楼层
回复 2# cenalulu


    确实是这样子的,Row_format=Fixed的时候,是插到"洞"里的,呵呵

论坛徽章:
8
综合交流区版块每周发帖之星
日期:2015-12-02 15:03:53数据库技术版块每日发帖之星
日期:2015-10-02 06:20:00IT运维版块每日发帖之星
日期:2015-10-02 06:20:00IT运维版块每日发帖之星
日期:2015-09-14 06:20:00金牛座
日期:2014-10-10 11:23:34CU十二周年纪念徽章
日期:2013-10-24 15:41:34酉鸡
日期:2013-10-19 10:17:1315-16赛季CBA联赛之北京
日期:2017-03-06 15:12:44
发表于 2010-06-07 12:44 |显示全部楼层
不错

用示例比较有说服力

论坛徽章:
0
发表于 2010-06-08 20:22 |显示全部楼层
本帖最后由 phphp 于 2010-06-08 20:28 编辑

内存表数据存储是一棵自增长的树,当没有空间插入记录时,会一次性分配从根节到叶子节点路径上的所有内存,所以不能按记录回收,图中颜色相同的代表是同时分配的内存,其中叶子节点存储记录。
于被删除的记录,会记录在del_link中,在插入新记录时复用,当del_link为空同时树中没有可用的空间时,树就会膨胀。

对于峰值记录数远大于平均记录数的应用,可定期重整回收内存。

内存数据结构.png

论坛徽章:
0
发表于 2010-06-10 13:26 |显示全部楼层
实践出真理。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP