MySQL 5.5对普通索引增删性能的优化

日期: 2011-11-01 作者:mysqlops 来源:TechTarget中国 英文

  传说5.5对于非聚集索引添加、删除性能上做了很大改善,在5.5之前版本中,ADD INDEX,DROP INDEX 需要拷贝整个表的,这样在生产环境上修改索引带来的风险很大。即便性能提高了,大家还是要慎重考虑索引的使用。先来实验下

  基本表:

  CREATE TABLE `task` (
  `UID` bigint(20) unsigned NOT NULL DEFAULT ’0′,
  `TDID` int(10) unsigned NOT NULL,
  `s` tinyint(3) unsigned NOT NULL DEFAULT ’0′,
  `date` int(8) unsigned DEFAULT ’0′,
  KEY `TDID` (`TDID`),
  KEY `UID` (`UID`)
  ) ENGINE=InnoDB DEFAULT CHARSET=utf8
  root@localhost : test 02:51:10> SELECT COUNT(*) FROM task;
  +———-+
  | COUNT(*) |
  +———-+
  | 1773940 |
  +———-+

  根据不同的索引类型进行测试

  Gereral Index

  root@localhost : test 05:53:16> ALTER TABLE task ADD KEY UID(UID);
  Query OK, 0 rows affected (7.15 sec)
  SHOW PROCESSLIST
  | 33 | root | localhost | test | Query | 5 | manage keys | ALTER TABLE task ADD KEY UID(UID) |
  root@localhost : test 02:52:26> ALTER TABLE task DROP INDEX UID;
  Query OK, 0 rows affected (0.08 sec)

  UK

  root@localhost : test 05:58:00> ALTER TABLE task ADD UNIQUE KEY UK_UT(UID,TDID,date);
  Query OK, 0 rows affected (7.99 sec)
  SHOW PROCESSLIST
  | 33 | root | localhost | test | Query | 4 | manage keys | ALTER TABLE task ADD UNIQUE KEY UK_UT(UID,TDID,date) |
  root@localhost : test 05:58:11> ALTER TABLE task DROP INDEX UK_UT;
  Query OK, 0 rows affected (0.09 sec)

  看到如此的变化,有什么感受呢?以后不必担心生产线上更改一个索引耗时太久。之前ALTER TABLE ADD DROP INDEX 进行经过这样的过程创建带有索引的新表—>从旧表COPY到新表à删除旧表àrename新表;但是5.5目前流程是:删除INNODB系统表与索引有关的数据,并且删除Mysql数据字典中于索引有关的数据就可以了,空间会被INNODB回收,以便于新建的表和索引直接使用。添加索引必须要扫描所有行,并且按照键值在Memory buffer和tempfile排序

  当然这只是普通索引,其实还有PK,UK,效果怎样?继续实验。

  CREATE TABLE `task` (
  `UID` bigint(20) unsigned NOT NULL DEFAULT ’0′,
  `TDID` int(10) unsigned NOT NULL,
  `s` tinyint(3) unsigned NOT NULL DEFAULT ’0′,
  `date` int(8) unsigned NOT NULL DEFAULT ’0′,
  KEY `TDID` (`TDID`),
  KEY `UID` (`UID`)
  ) ENGINE=InnoDB DEFAULT CHARSET=utf8

  PK

  ALTER TABLE task ADD PRIMARY KEY(UID,TDID,date);
  Query OK, 0 rows affected (19.89 sec)
  SHOW PROCESSLIST;
  |33 | root | localhost | test | Query | 19 | manage keys | ALTER TABLE task ADD PRIMARY KEY(UID,TDID,date)
  ALTER TABLE task DROP PRIMARY KEY;
  Query OK, 1773940 rows affected (16.07 sec)
  SHOW PROCESSLIST;
  | 33 | root | localhost | test | Query | 3 | copy to tmp table | ALTER TABLE task DROP PRIMARY KEY |

  UK

  ALTER TABLE task ADD UNIQUE KEY UK_UT(UID,TDID,date);
  Query OK, 0 rows affected (27.08 sec)
  show processlist;
  | 33 | root | localhost | test | Query | 8 | manage keys | ALTER TABLE task ADD UNIQUE KEY UK_UT(UID,TDID,date) |
  ALTER TABLE task DROP INDEX UK_UT;
  Query OK, 1773940 rows affected (20.76 sec)
  show processlist;
  | 33 | root | localhost | test | Query | 9 | copy to tmp table | ALTER TABLE task DROP INDEX UK_UT |

  两种情况都耗时很长啊!看看是何原因?对于聚集索引的重建涉及到数据的问题,必须新建表并COPY数据,并且更新Second index数据。

  而上面看到的两个UK,主要是因为UK字段如果not null ,Mysql将会按照UK去建立聚集索引,第一中情况date为null ,所以为普通索引;第二种情况date为not null,建立聚集索引,所以重建数据

  提示:

  其中的manage keys 的状态表示The server is enabling or disabling a table index

  当second index被create和drop的时候,该表会被加上SHARE MODE锁,只能读,不能写;如果cluster index被create和drop的时候,会被加上exclusive mode锁,任何操作都会被block

我们一直都在努力坚持原创.......请不要一声不吭,就悄悄拿走。

我原创,你原创,我们的内容世界才会更加精彩!

【所有原创内容版权均属TechTarget,欢迎大家转发分享。但未经授权,严禁任何媒体(平面媒体、网络媒体、自媒体等)以及微信公众号复制、转载、摘编或以其他方式进行使用。】

微信公众号

TechTarget微信公众号二维码

TechTarget

官方微博

TechTarget中国官方微博二维码

TechTarget中国

电子邮件地址不会被公开。 必填项已用*标注

敬请读者发表评论,本站保留删除与本文无关和不雅评论的权力。

作者

mysqlops
mysqlops

相关推荐