4

我需要使用 LOAD 数据将数据加载到 MYSQL 表中。加载时,我需要根据某些条件将数据标志列设置为适当的值。数据插入可以从不同的脚本发生,我想使用 BEFORE INSERT 触发器来集中处理过程。现在的问题是 INSERT 过程需要很多时间。作为示例,当我从命令行使用 SOURCE 命令和 500 000 条记录的文件来放置测试数据时,从空白表开始插入 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
4

1 回答 1

0

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

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

于 2013-09-20T05:13:34.487 回答