触发器性能降级(使用或不使用)



我已经创建了这个触发器:

DELIMITER $$
CREATE TRIGGER `increment_daily_called_count` BEFORE UPDATE ON `list` 
FOR EACH ROW begin
  if (NEW.called_count != OLD.called_count) then
    set NEW.daily_called_count = OLD.daily_called_count(NEW.called_count-OLD.called_count);
    set NEW.modify_date = OLD.modify_date;    
  end if;
end
$$
DELIMITER ;

它运行的数据库表由较大系统中的100个不同脚本访问和使用,触发的原因是,我不必在这些脚本中查找called_count可能更新的每一个小地方。。。

我担心的是,因为这个特定的表会不断地被修改(我说的是每秒几十次(,这会给数据库带来不必要的压力吗?从长远来看,在无数的脚本中查找所有called_count更新查询并添加daily_called_count=daily_colled_count+1,我会更好吗?

一些细节我想知道答案在这里:

  • 这个触发器的使用是否本质上使这3个单独的更新查询成为一个单独的查询,或者MySQL是否足够智能,可以捆绑这些查询
  • 是否存在使用触发器查找和修改原始查询的性能参数
  • 这个触发会不会导致我没有预料到的任何意外的怪异

两个免责声明:

  1. 我已经很长时间没有使用MySQL了,也从来没有使用过触发器。我只能从使用RDBMS的一般经验说起
  2. 真正确定任何事情的唯一方法是运行性能测试

也就是说,我试图用半受过教育的猜测(根据经验(来回答:

这个触发器的使用是否本质上使这3个单独的更新查询成为一个单独的查询,或者mysql是否足够智能,可以捆绑这些查询?

我不认为这是语句执行意义上的单独更新。但是,您正在向每一行添加计算开销成本。

然而,我更担心的是这个触发器的逐行性质。它的字面意思是FOR EACH ROW。一般来说,与基于SET的操作相比,在RDBMS中逐行操作的扩展性较差。MS SQL Server运行语句级触发器,其中传入受影响的整组行,因此不需要逐行操作。这可能不是MySQL触发器中的一个选项——我真的不知道。

是否存在使用触发器查找和修改原始查询的性能参数?

这肯定会使系统减少工作量。从数字上看,性能的影响有多大,我不能说。你必须进行测试。如果只有1%的差异,那么触发器可能很好。如果它是50%,那么,搜索所有代码是值得的。由于查找代码是一种负担,我怀疑它要么嵌入在应用程序中,要么动态地来自ORM。如果是这样的话,只要触发器的性能成本是可以接受的,我宁愿坚持使用触发器,因为它在数据库中保留了特定于数据库的细节。

测量,测量,测量。

这个触发会不会导致我没有预料到的任何意外的怪异?

脑海中浮现出缓存。如果这些列是应用程序读取和缓存的内容的一部分,那么它的缓存无效可能与它认为更改了数据有关。如果数据库更改了它下面的数据,就像使用触发器一样,缓存可能会导致处理过时的数据。

首先,感谢@Brandon的回复。我建立了自己的脚本和测试数据库来进行基准测试并解决我的问题。。。虽然我对第1点和第3点没有很好的答案,但我对性能问题有一个答案。。。

需要注意的是,我在我们的开发服务器上使用的是10.0.24-MariaDB,当时它上没有运行任何其他东西。

这是我的结果。。。

更新100000行:

TRIGGER QUERY TIME: 6.85960197 SECONDS
STANDARD QUERY TIME: 5.90444183 SECONDS

更新200000行:

TRIGGER QUERY TIME: 13.19935203 SECONDS
STANDARD QUERY TIME: 11.88235188 SECONDS

你们可以自己决定走哪条路。

最新更新