我需要使用 LOAD 数据将数据加载到 MYSQL 表中。加载时,我需要根据某些条件将数据标志列设置为适当的值。数据插入可以从不同的脚本发生,我想使用 BEFORE INSERT 触发器来集中处理过程。现在的问题是 INSERT 过程需要很多时间。作为示例,当我从命令行使用 SOURCE 命令和 500 000 条记录的文件来放置测试数据时,从空白表开始插入 550 条记录的块大约需要 19 秒。当我使用大约 2300 条记录的 LOAD 数据时(这是可以定期发生的理想插入,除非之前的插入失败并且要插入的数据累积),大约需要 90 秒才能完成。
我想知道:
如果我无论如何都可以提高这个触发器的性能,或者触发器通常很慢?
如果我将相同的逻辑转移到外部触发器到处理中的常规 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