表上触发器导致慢查询

触发器导致慢查询
情况说明:慢日志每天几乎同一时刻都会有一条删除的慢查询,而且语句一样,除了日期。然后发现表上只有一个主键,没有其它索引,看执行计划是全表扫描,但count一下总共也就900多行,执行3秒钟,不能忍。给表上这个时间字段加上索引,删除是按照时间删的,看着扫描行数下来了,但是一执行还是3秒多,啥情况?

我把整张表dump出来,准备在自己删的差不多时候,再导回来。无意间打开导出的sql,发现该表上有一个删除行之后执行的触发器。

然后我就把触发器删除了,发现执行删除sql就很快,而且全表扫描也很快,但是触发器存在的情况下就极慢。

为啥呢???

我想看看我这条语句到底执行多久,于是我打开了profile功能。
通过set profiling=1
set session profiling_history_size = 100;

我这个sql一次删除31行
然后执行时间是2.28秒

show profiles
发现每个触发器平均执行0.07秒
0.07乘31等于2.17秒
这样的话,sql语句执行就是0.11秒

然后我又试了删除4行
发现总的执行时间是0.36秒,如果按触发器每条0.07秒,4条就是0.28秒,
那么sql的执行时间就是0.08秒。
基本上验证了一个猜测,执行的sql如果触发了触发器,那么执行的总时间就是sql执行时间+触发器执行时间。

如果更改的行数少,比如我这个4条,时间还能接受,如果更改大部分行,那么时间相当可怕,因为变更了多少行,触发器就执行多少次,时间累加。

原文地址:http://blog.51cto.com/8370646/2150164

时间: 2024-08-24 12:53:02

表上触发器导致慢查询的相关文章

RDS MySQL 表上 Metadata lock 的产生和处理

1. Metadata lock wait 出现的场景 2. Metadata lock wait 的含义 3. 导致 Metadata lock wait 等待的活动事务 4. 解决方案 5. 如何避免出现长时间 Metadata lock wait 导致表上相关查询阻塞,影响业务 1. Metadata lock wait 出现的场景 创建.删除索引 修改表结构 表维护操作(optimize table.repair table 等) 删除表 获取表上表级写锁 (lock table tab

无法在同一张表上查询和更新的问题解决方法

一.问题引入 要在一张已存在并且有数据的表上建一个唯一索引,由于建索引的这列有很多重复的数据,导致无法建unique索引!要一条条数据手工删除吗?不!我是工程师,我要用技术的手段删除重复数据.写了一个删除重复数据的sql,如下: delete from entity_tag where id not in (select max(id) from entity_tag group by code ) 写完了,十分兴奋的跑一下这个sql,结果大跌眼镜 [语句1]: delete from enti

Flink:动态表上的连续查询

用SQL分析数据流 越来越多的公司在采用流处理技术,并将现有的批处理应用程序迁移到流处理或者为新的应用设计流处理方案.其中许多应用程序专注于分析流数据.分析的数据流来源广泛,如数据库交易,点击,传感器测量或物联网设备. Apache Flink非常适合流式分析,因为它提供了事件时间语义支持,恰一次的处理,并同时实现了高吞吐和低延迟.由于这些特性,Flink能够近乎实时地从大量输入流计算确切的和确定性的结果,同时在出现故障时提供恰一次处理的语义. Flink的流处理核心API,DataStream

Sql语句不能识别Go的解决办法(动态创建表的触发器)

问题来源 用sqlserver直接打开sql文本,执行没问题,但是当用Sqlcommand类执行cmdtext命令文本时总是失败报错. 原因分析及解决 用数据库直接执行sql语句没问题,甚至还可以用Go来进行分批处理,但是当你用链接类访问数据库,并执行sql语句时就有些限制,如下: System.Data.SqlClient.SqlCommand cmd; try { using (System.Data.SqlClient.SqlConnection newconn = new System.

如何应付表数据过大的查询问题?(如何尽量避免大表关联)

原文:如何应付表数据过大的查询问题?(如何尽量避免大表关联) 一般来说,对于做B/S架构的朋友来说,更有机会遇到高并发的数据库访问情况,因为现在WEB的普及速度就像火箭升空,同时就会因为高访问量带来一系列性能问题,而数据库一直是用户与商人之间交流的重要平台.用户是没有耐心忍受一个查询需要用上10秒以上的,或者更少些,如果经常出现服务器死机或者是报查询超时,我想那将是失败的项目.做了几年的WEB工作,不才,一直没有遇到过大访问量或者是海量数据的情况.这里并不是说没有海量数据的项目就不是好项目,要看

ORACLE 在重要的表上限制某些IP、用户的恶意操作

1,问题描述          oracle默认账号是没有限制ip的,这样的隐患就在于,如果我知道了oracle账号用户名密码,我只要能连接到db,就可以对db进行操作,这样对于线上的db来说是很危险的,因为有些非dba人员,比如开发人员.测试人员一不小心误删除了线上的数据,就惨了,坑太大不敢看.所以查了查,找到一种办法,在一些重要的表上加触发器来限制用户对线上db的表的操作. 2,触发器编写 如果开全局的sql审计,消耗性能太大,不太合适,想来只有在某些重要的表上做限制,初步解决问题了. 1)

Oracle怎么查外键建在哪个表上

怎样查外键建在哪个表上 有时候删除某张表记录的时候,会报错外键约束不能删除. 如果不了解表之间的关系,可以通过以下语句查询到外键是建在哪张表上的: select * from dba_constraints where constraint_name='xxx' and constraint_type = 'R'; 例如:我的程序日志中报如下错误,我要知道外键是在那个表上. 2015-09-08 18:28:18 [ main:261597003 ] - [ ERROR ] java.sql.S

堆表上的转发记录

今天这篇文章我想谈下堆表上特有的性能问题:转发记录(Forwarding Records).首先我们要澄清下什么是堆表:堆表就是没有聚集索引定义的表.它对插入新记录非常快,但当你读取数据时非常慢.读取数据会在你的存储子系统上引入随机存取(random I/O),有时候当你碰到转发记录,它会进一步降低你的读取性能. 为什么会有转发记录? 当堆表里的记录需要移动到不同的物理位置时,SQL Server使用转发记录.假设你有一个变长列的表,首先你在堆表里插入一些记录,这个时候你没有在变长列里存储任何数

表上999个非聚集索引——你怎么看?

对于数据获取,如果查询优化器在执行计划里选择了索引,那么SQL Server里的每个索引可以提高你的查询性能.但在另一方面,每个索引也会伤及你的性能,因为在INSERT,UPDATE和DELETE期间,每个索引需要被维护.因此对于你的工作量,尽可能创建少的索引非常重要——不然在写操作期间,你会有巨大的性能问题. 当你在表上定义了最大999个索引,SQL Server会如何反应?我从未在表上创建多大999个索引,因此详细验证下这个行为,并讨论下它引入的所有副作用,会是个很好的锻炼. 我们来创建一个