0

この手順は機能していますが、実行に 5 分かかります。もっと速くて簡単な方法はありますか?

検査のリストを含むテーブルが 1 つあります。後日、同じテーブルに挿入されたフォローアップ検査があります。フォローアップ検査のシリアル番号は同じですが、日付スタンプが異なります。どの検査がフォローアップ検査を完了していないかを調べる必要があります。

最初に、type_due=3 で、inspection_completed としてマークされていないすべての serial_numbers を取得しています。

次に、この serial_numbers のリストから、inspection_completed としてマークされた後の date_stamp に同じ serial_number を持つ検査があるかどうかを確認しています。

したがって、何か他のものが存在する場合にのみ選択されます。2 番目のクエリに、同じ serial_number、より大きな日付、null ではない Inspection_completed 値を持つ結果がある場合、最初のクエリの結果のプールの削除。

このクエリが実行されるたびに、Inspections_due テーブルを切り捨てています。これは、Inspections テーブルに追加された新しいフォローアップ検査によって、Inspections_due テーブルの一部の結果が無効になるためです。

最初のクエリから約 9,000 件の結果があります。おそらく、別のクエリを作成して Inspections_due テーブルの無効な結果を削除し、このクエリが実行されるたびに新しいレコードのみを Inspections_due に追加する方が全体的に高速になるでしょう。

注: Select Exists の代わりに Select count(*) を試しましたが、速度の違いはあまりありませんでした。

どんな提案も素晴らしいでしょう!ありがとう

CREATE PROCEDURE create_due_inspections()
BEGIN

  DECLARE done INT DEFAULT FALSE;
  DECLARE iid int(10); #unique inspection id
  DECLARE sn VARCHAR(16); #serial number
  DECLARE dt date; #date_stamp
  DECLARE `result` int;

  DECLARE cur1 CURSOR FOR SELECT inspection_id, serial_number, date_stamp FROM 
      Inspections where type_due = '3' and inspection_completed is null;

  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

  TRUNCATE TABLE `Inspections_due`; # clean out the old results

  OPEN cur1;

  read_loop: LOOP

    FETCH cur1 INTO iid,sn,dt;
    IF done THEN
      LEAVE read_loop;
    END IF;

    SET `result` := (select exists(Select inspection_id from Inspections
where serial_number = sn and date_stamp > dt and inspection_completed is not null));

    IF  `result` THEN
        insert into Inspections_due values(iid);
    END IF;

  END LOOP;

  CLOSE cur1;
END;
4

1 に答える 1

1

カーソルを避け、セットで作業する必要があります:

INSERT into Inspections_due 
SELECT 
      inspection_id as iid 
FROM 
      Inspections I1 
where 
      type_due = '3' and inspection_completed is null
      and exists(
           Select inspection_id 
           from Inspections I2
           where I2.serial_number = I1.serial_number 
                 and I2.date_stamp >  I1.date_stamp
                 and inspection_completed is not null))

また、exists サブクエリを内部結合に置き換えます

SELECT distinct
      inspection_id as iid 
FROM 
      Inspections I1 
inner join  
      Inspections I2
         on
                 I2.serial_number = I1.serial_number 
                 and I2.date_stamp >  I1.date_stamp
                 and inspection_completed is not null
于 2012-10-23T08:10:55.427 に答える