MySQL 触发前性能问题

标签 mysql performance triggers

我需要使用 LOAD 数据将数据加载到 MYSQL 表中。加载时,我需要根据特定条件将数据标志列设置为适当的值。数据插入可以从不同的脚本发生,我想使用 BEFORE INSERT 触发器来集中处理。现在的问题是 INSERT 过程需要很多时间。作为示例,当我在命令行中使用 SOURCE 命令和一个包含 500 000 条记录的文件来放置测试数据时,一个 block 从空白表开始插入 550 条记录大约需要 19 秒。当我使用包含大约 2300 条记录的 LOAD 数据时(这是可以定期发生的理想插入,除非之前的插入失败并且要插入的数据累积),大约需要 90 秒才能完成。

我想知道:

  1. 我是否可以按原样提高此触发器的性能,或者触发器通常很慢?

  2. 如果我在处理过程中将相同的逻辑转移到外部触发器到常规 SQL,性能将会提高。(触发器与常规 SQL)。抱歉,出于某些原因,我无法测试这种情况。此外,由于我有许多可以从中插入数据的脚本,所以我想避免这样做。

我的触发逻辑是

CREATE TRIGGER `mydb`.`flag_data` BEFORE INSERT ON `mydb`.`mytable`

FOR EACH ROW BEGIN
    DECLARE threshold_val FLOAT;
    DECLARE time_upper_limit_1 FLOAT;
    DECLARE time_upper_limit_2 FLOAT;
    SET threshold_val = 400;
    SET time_upper_limit_1 = 4000;
    SET time_upper_limit_2 = 8000;

    SET new.data_flag=(SELECT CASE COUNT(*) WHEN 0 THEN 2 ELSE (SELECT CASE WHEN new.rf >@threshold_val THEN 5 WHEN new.rf < 0 THEN 5 ELSE (SELECT CASE WHEN MINUTE( new.rec_time) Mod 15 <> 0 THEN 1 ELSE new.data_flag END) END) END FROM vw_active_stn_list WHERE stn_id=new.stn_id);

    IF (new.data_flag = 0) THEN
        IF (new.rmode = 'H') THEN
            SET new.data_flag=(SELECT CASE WHEN COUNT(*)>0 THEN 2 ELSE 0 END FROM vw_mf_list WHERE stn_id=new.stn_id);
        ELSEIF (new.rmode = 'F') THEN
            SET new.data_flag=(SELECT CASE WHEN COUNT(*) > 0 THEN 4 ELSE (SELECT CASE WHEN ISNULL(TIMESTAMPDIFF(MINUTE,new.rec_time,Now()))=1 THEN 1 WHEN TIMESTAMPDIFF(MINUTE,new.rec_time,Now()) NOT BETWEEN 0 AND @time_upper_limit_1 THEN 1  ELSE 0 END ) END from stn_mf WHERE ((new.rec_time BETWEEN mf_start_time AND mf_end_time) OR (mf_start_time <= new.rec_time AND mf_end_time IS NULL)) AND stn_id=new.stn_id AND (stn_type='X' OR stn_type='Y'));
        ELSEIF (new.rmode = 'S' OR new.rmode = 'M') THEN
            SET new.data_flag=(SELECT CASE WHEN COUNT(*) > 0 THEN 4 ELSE (SELECT CASE WHEN ISNULL(TIMESTAMPDIFF(MINUTE,new.rec_time,Now()))=1 THEN 1 WHEN TIMESTAMPDIFF(MINUTE,new.rec_time,Now()) NOT BETWEEN 0 AND @time_upper_limit_2 THEN 1  ELSE 0 END ) END from stn_mf WHERE ((new.rec_time BETWEEN mf_start_time AND mf_end_time) OR (mf_start_time <= new.rec_time AND mf_end_time IS NULL)) AND stn_id=new.stn_id AND (stn_type='X' OR stn_type='Y'));
        END IF;
    END IF;
END

最佳答案

批量加载的触发器速度较慢。在您的情况下,切换到标准 SQL 而不是触发器将是有益的。

如果插入的频率越来越低,触发器可能会很有用。

关于MySQL 触发前性能问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18803385/

相关文章:

c++ - OpenGL 在我的电脑上性能低下

asp.net - updatepanel asynpostbacktrigger 不会抛出定义的事件?

mysql - 仅当在另一个字段中输入非 NULL 值时才更新时间戳

mysql - 如何解决sql中的重复值

php - 验证数据库中是否存在输入的用于请求密码的电子邮件

php - 从 mysql 切换到 PDO,登录脚本不再有效

php - 查询一个查询 - MySQL 和 PHP

linux - 仅显示带有 Perf 注释的源代码

jquery-animate - jquery 或动画 png/gif 哪个更适合网页上的图像动画?

mysql - 为什么MySQL触发器变量不能处理特殊字符?