LOAD データを使用して MYSQL テーブルにデータをロードする必要があります。ロード中に、特定の条件に基づいてデータ フラグ列を適切な値に設定する必要があります。データ挿入はさまざまなスクリプトから発生する可能性があり、プロセスを集中化するために BEFORE INSERT トリガーを使用することを考えました。ここでの問題は、INSERT プロセスに時間がかかることです。サンプルとして、コマンド ラインから SOURCE コマンドを使用して、テスト データを配置するために 500 000 レコードのファイルを使用した場合、550 レコードのブロックは、空のテーブルから始まる挿入に約 19 秒かかります。約 2300 レコードの LOAD データを使用した場合 (これは、以前の挿入が失敗し、挿入されるデータが蓄積されない限り、定期的に発生する理想的な挿入です)、完了するまでに約 90 秒かかりました。
私が知りたいのですが:
とにかくこのトリガーのパフォーマンスをそのまま改善できるか、または一般的にトリガーが遅いですか?
同じロジックを通常の SQL の処理に外部トリガーにシフトすると、パフォーマンスが向上します。(トリガー vs 通常の 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