性能分析:hash索引导致delete慢

前端时间,应用人员上报一个性能问题:在生产环境中,每天凌晨时段数据库运行很慢,一些EVENT运行失败,导致一部分应用功能异常。

根据应用人员提供的时间段,对数据库进行排查。

先对主机CPU、IO、数据库连接等监控历史数据进行分析,确认故障时间线,缩小时间范围。

从上图看到0:30左右,数据库活动连接由0增到200,1:09活动连接数增到400+,数据库连接异常增高,需要进一步分析数据库此时间在执行什么操作。

对抓取到的历史数据(主机部署了shell监控脚本)进行分析:在0:30,数据库正在对表_1030做delete操作,其他线程在等待表锁。

综合以上,梳理出故障时间线:

监控数据显示,0:30表_1030进行delete操作,该操作在1:15分左右才执行完成,该操作运行了40+分钟左右,此期间表_1030的select操作被阻塞,导致数据库连接从0升高到200,最大达到400,应用异常:

造成阻塞的SQL为:

DELETE FROM _1030 WHERE _1030.F05 <=  NAME_CONST(‘_current_date‘,_latin1‘2016-01-17 00:30:00‘ COLLATE ‘latin1_swedish_ci‘)

结合以上,有2个疑问:

该delete语句为什么会产生表锁?

该delete语句为什么这么慢?能否优化?

([email protected]) [(none)]> show create table S11._1030 \G

*************************** 1. row ***************************

Table: _1030

Create Table: CREATE TABLE `_1030` (

`F01` int(10) unsigned NOT NULL AUTO_INCREMENT,

`F02` char(45) NOT NULL,

`F03` datetime NOT NULL,

`F04` int(10) unsigned DEFAULT NULL,

`F05` datetime NOT NULL,

`F06` varchar(40) NOT NULL,

`F07` varchar(40) DEFAULT NULL,

PRIMARY KEY (`F01`),

UNIQUE KEY `F02` (`F02`) USING HASH,

KEY `F06` (`F06`) USING HASH,

KEY `F07` (`F07`) USING HASH

) ENGINE=MEMORY DEFAULT CHARSET=utf8

1 row in set (0.00 sec)

通过查看发现该表是heap表,heap表数据都在内存里,heap性能应该是很快的,该delete语句为什么这么慢?

在测试环境进行测试,DELETE _1030 50w的数据量需要58s,慢的不合常理。删除该表的索引后,delete 1s内完成。这里基本确认索引维护代价太大导致。

添加btree索引,再次测试,delete 1s内完成。确认是hash索引造成。

优化方案:

  1. 把delete改为没有where条件的全表delete或truncate(该表数据是缓存数据)。
  2. 把HASH索引改为BTREE索引。

注:由于btree索引占用的内存空间很大(经测试,btree索引占用空间是hash索引的6倍以上),数据库主机当时内存紧张,所以优先使用方案1。

时间: 2024-08-27 23:18:18

性能分析:hash索引导致delete慢的相关文章

外键约束列没建索引导致大量library cache pin/library cache lock

清空一个100多万行的大表的数据,发现一直执行了几个小时: delete B001.T_B11; 通过以下SQL进行跟踪,发现经常会出现library cache pin和library cache lock的等待,怀疑有大量的recursive sql在执行,于是对这个session做了10046: 发现有大量的如下SQL执行,每删除1行T_B11,都会执行下面2条SQL一次, PARSING IN CURSOR #3 len=93 dep=2 uid=0 oct=3 lid=0 tim=14

MySql的Myisam索引、Innodb索引 、count性能分析个人见解

在MySQL 5.6下做测试的. Myisam引擎: 当创建一个数据表时,mysql会生成3个文件,分别是(如表:test): test.frm.test.MYD.test.MYI文件, test.frm是表结构,test.MYD是存放数据的文件,test.MYI是存放索引的文件, 索引文件存储关系key-value,value是存储一个指向test.MYD中数据行的指针. 在这里就可以看出myisam引擎的数据与索引是分开存储的. 当使用索引搜寻数据时,mysql服务器会先到test.MYI文

Mysql 自定义HASH索引带来的巨大性能提升

有这样一个业务场景,需要在2个表里比较存在于A表,不存在于B表的数据.表结构如下: T_SETTINGS_BACKUP | CREATE TABLE `T_SETTINGS_BACKUP` ( `FID` bigint(20) NOT NULL AUTO_INCREMENT, `FUSERID` bigint(20) NOT NULL COMMENT '用户ID', `FDEVICE` varchar(64) NOT NULL DEFAULT '' COMMENT '用户设备号(SN)', `F

Oracle性能分析9:重建索引

当索引出现问题时,会导致严重的性能问题,索引问题包括索引不可用.索引碎片导致性能下降,我们需要一些手段在检测索引的问题,并解决这些问题.这一篇将为你讲述怎么定位索引问题,并提供了解决的办法. 索引不可用 索引不可用的原因有很多,包括: 1)索引空间耗尽,导致SQL*Loader更新索引失败: 2)创建索引的过程中实例失败: 3)唯一键有重复值: 4)某个索引的顺序与sorted indexes子句中指定的顺序不同: 5)移动表或表分区(alter table move和alter table m

mysql索引结构原理、性能分析与优化

原文  http://wulijun.github.com/2012/08/21/mysql-index-implementation-and-optimization.html 第一部分:基础知识 索引 官方介绍索引是帮助MySQL高效获取数据的数据结构.笔者理解索引相当于一本书的目录,通过目录就知道要的资料在哪里, 不用一页一页查阅找出需要的资料. 唯一索引(unique index) 强调唯一,就是索引值必须唯一. 创建索引: create unique index 索引名 on 表名(列

由浅入深探究mysql索引结构原理、性能分析与优化

转载自:http://www.phpben.com/?post=74 第一部分:基础知识: 索引 官方介绍索引是帮助MySQL高效获取数据的数据结构.笔者理解索引相当于一本书的目录,通过目录就知道要的资料在哪里,不用一页一页查阅找出需要的资料.关键字index ------------------------------------------------------------- 唯一索引 强调唯一,就是索引值必须唯一,关键字unique index 创建索引: 1.create unique

转:由浅入深探究mysql索引结构原理、性能分析与优化

摘要: 第一部分:基础知识 第二部分:MYISAM和INNODB索引结构 1. 简单介绍B-tree B+ tree树 2. MyisAM索引结构 3. Annode索引结构 4. MyisAM索引与InnoDB索引相比较 第三部分:MYSQL优化 1.表数据类型选择 2.sql语句优化 (1)     最左前缀原则 (1.1)  能正确的利用索引 (1.2)  不能正确的利用索引 (1.3)  如果一个查询where子句中确实不需要password列,那就用“补洞”. (1.4)  like

由浅入深探究 MySQL索引结构原理、性能分析与优化

第一部分:基础知识: 索引 官方介绍索引是帮助MySQL高效获取数据的数据结构.笔者理解索引相当于一本书的目录,通过目录就知道要的资料在哪里,不用一页一页查阅找出需要的资料.关键字index --------------------- 唯一索引 强调唯一,就是索引值必须唯一,关键字unique index 创建索引: 1.create unique index 索引名 on 表名(列名); 2.alter table 表名 add unique index 索引名 (列名); 删除索引: 1.

Mysql 自定义HASH索引带来的巨大性能提升----[真相篇]

推倒重来 俗话说no zuo no die why you try,这时候我又忍不住zuo了,吭哧吭哧的把解决过程发上博客,向全世界宣布,哥又搞定个难题. 剧情的发展往往是看起来主角完全掌握了局势的情况下,会突然跳出来一个很牛的反面人物,然后搞得主角很惨,搞的过程中主角开始小宇宙爆发,然后逆袭.这次也不例外.踢场子的人该出现了 一顿狂侃之后,发现我原来牛逼的分析,完全经不起推敲.几个问题 1)  在未做HASH索引之前,为什么大表的ROWS那么大,相当于全表扫描 2)  既然SN是唯一索引,那么