0

2 つの異なるプログラム用の 2 つのテーブルがあります。各プログラムには特定の program_instance があります (program_instance) はプログラムの年です。

1 つのテーブルは「登録者」と呼ばれ、もう 1 つのテーブルは「ノミネーション」です。技術的に関連していない 2 つのプログラム用です。

両方のテーブルから過去の参加者の数を取得しようとしています。参考のため:

program_instance_id:

  • 5 = GC 2014
  • 3 = GC 2013
  • 1 = GC 2012
  • 4 = GE 2013
  • 2 = GE 2012

そこで、enrollees テーブルでこのクエリを実行したところ、913 ミリ秒で結果が得られました。

SELECT      count(*) AS prev_enrollees
FROM       outreach.enrollees e1
WHERE e1.program_instance_id = 5 AND EXISTS 
    (SELECT * FROM outreach.enrollees e2
            WHERE e1.first_name = e2.first_name 
            AND e1.last_name = e2.last_name 
            AND e1.address1 = e2.address1 
            AND e1.state = e2.state 
            AND e1.zip = e2.zip 
            AND e2.program_instance_id < 5);

私の理解では、このクエリは、現在の年 (program_instance_id = 5) の登録者が以前に別の年に登録した「enrollees」テーブルの行数を示します。それが生成する結果は、私の理解ではかなり正確です。

だから...「指名」テーブルでこのEXACTクエリ(テーブル名を変更)を実行しました。nominations テーブルは、「enrollees」テーブルとほぼ同じ構造になっています (一部の列は異なりますが、人物の情報フィールドは同じです)。このクエリは、キャンセルするまでに 30 分以上実行されました。登録者のテーブルにあったように、ほぼ瞬時に結果が表示されるわけではなく、なぜもっと時間がかかるのかわかりません。

テーブルにはもっと多くの行があると想像できますが、登録者テーブルには指名テーブルよりも約 5 万行多くあります。

私も試しました:

SELECT     count(*) AS prev_enrollees
FROM       outreach_grow_education.nominations e1
JOIN  outreach_grow_education.nominations e2 ON e1.first_name = e2.first_name 
AND e1.last_name = e2.last_name 
AND e1.address1 = e2.address1 
AND e1.state = e2.state 
AND e1.zip = e2.zip 
AND 4 = e2.program_instance_id
WHERE e1.id IS NOT NULL AND e1.program_instance_id = 2;

ああ、同じ結果に。登録者の即時結果、指名の終了はありません。

私が達成しようとしていることに対して、終わりのないサイクルを引き起こさない他の代替手段はありますか?

4

1 に答える 1

0

2 つのテーブルのインデックス、特に JOIN 句で使用する列 (first_name、last_name、address1、state、zip、および program_instance_id) を確認することをお勧めします。これらの列の 1 つ以上が、「推薦者」ではなく「登録者」テーブルで索引付けされている可能性があります。

于 2013-10-17T23:35:07.857 に答える