MySQL触发性能问题之前

时间:2013-09-14 15:35:40

标签: mysql performance triggers

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

我想知道:

  1. 如果我能够改善这个触发器的性能,或者触发器一般都很慢?

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

  3. 我的触发逻辑是

    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
    

1 个答案:

答案 0 :(得分:0)

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

如果插入次数较少且频率较低,则触发器可能很有用。