触发性能下降(使用或不使用)

aja*_*515 4 mysql triggers

我创建了这个触发器:

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 ;
Run Code Online (Sandbox Code Playgroud)

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

我担心的是,因为这个特定的表不断被修改(我说的是每秒几十次),这是否会给数据库带来过度的压力?从长远来看,我是否会更好地在无数脚本中搜索所有 Called_count 更新查询并添加 daily_used_count = daily_used_count+1 ?

我想知道一些具体问题的答案:

  • 使用此触发器是否本质上使这 3 个单独的更新查询(它曾经是单个查询)成为可能,或者 MySQL 是否足够智能来捆绑这些查询?
  • 使用触发器寻找和修改原始查询是否存在性能争议?
  • 这个触发器是否会导致我没有预料到的任何不可预见的奇怪现象?

Bra*_*don 5

两项免责声明:

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

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

使用此触发器本质上是否使这 3 个单独的更新查询(它曾经是单个查询)成为可能,或者 mysql 是否足够智能来捆绑这些查询?

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

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

使用触发器寻找和修改原始查询是否存在性能争议?

这肯定会让系统做更少的工作。从数字上看,性能影响有多大,我不能说。你必须进行测试。如果只有 1% 的差异,则触发器可能没问题。如果是 50%,那么就值得寻找所有代码。由于寻找代码是一种负担,我怀疑它要么嵌入在应用程序中,要么动态地来自 ORM。如果是这种情况,只要触发器的性能成本可以接受,我宁愿坚持使用触发器,因为它在数据库中保留特定于数据库的详细信息。

测量,测量,测量。

这个触发器是否会导致我没有预料到的任何不可预见的奇怪现象?

我想到了缓存。如果这些列是应用程序读取和缓存的内容的一部分,则其缓存失效可能与它认为更改了数据的时间有关。如果数据库更改其下面的数据(例如使用触发器),则缓存可能会导致处理过时的数据。