0

MySQLのサブセレクトパフォーマンスに関するアドバイスが必要です。変更できない理由で、JOINを使用してクエリフィルターを作成することはできません。WHEREに別のAND句を追加することしかできません。

のパフォーマンスは何ですか:

select tasks.*
from tasks
where 
  some criteria
  and task.project_id not in (select id from project where project.is_template = 1);

に比べ:

select tasks.*
from tasks, project
where
  some criteria
  and task.project_id = project.id and project.is_template <> 1;

is_template = 1のプロジェクトは比較的少数であり、is_template<>1のプロジェクトは多数存在する可能性があることに注意してください。

何も変更できず、フィルタリングできない場合、副選択なしで同じ結果を達成する他の方法はありますか?

4

4 に答える 4

5

2 つ目の方法は 1 つの選択しか必要としないため、より効率的だと思いますが、念のため、各クエリを EXPLAIN して結果を確認する必要があります。

EXPLAIN select tasks.*
from tasks
where 
  some criteria
  and task.project_id not in (select id from project where project.is_template = 1);

EXPLAIN select tasks.*
from tasks, project
where
  some criteria
  and task.project_id = project.id and project.is_template <> 1;
于 2008-12-04T16:03:13.790 に答える
1

この 2 つにどの程度の違いがあるかは、「いくつかの基準」とは何か、およびそれが提供するインデックスを使用する機会に大きく依存する可能性があります。ただし、プロジェクトを持たないタスクがある場合、結果に関しては同等ではないことに注意してください。2番目はこれと同等です:

select tasks.*
from tasks
where 
  some criteria
  and task.project_id in (select id from project where project.is_template <> 1);
于 2008-12-04T16:14:49.723 に答える
0

私は最初のものがより良くスケーリングするかもしれないと思います:

結合を行うと、内部でmysqlは、指定された結合条件に従って結合された2つのテーブルで構成される一種の一時テーブルを作成します。結合条件を指定していないため、すべてのプロジェクトに対してすべてのタスクがリストされた一時テーブルが作成されます。where句を適用する前にこれを行うことはかなり確信しています(ただし、explainツールで確認してください)。

結果:それぞれが10個ある場合、10*10行=100になります。数値が増えるにつれてこれがどのように大きくなるかを確認できます。次に、whereをこの一時テーブルに適用します。

対照的に、サブクエリは各テーブルから関連する行のみを選択します。

しかし、スケーリングが問題にならない限り、それは本当に重要ではないと思います。

于 2008-12-04T16:18:59.873 に答える
0

MySQLバージョン6.0未満のペストのようなサブクエリは避けてください。6.0がまだ開発のアルファ段階にあることを考えると、6.0を使用しているとは思えません。AFAIK、MySQLオプティマイザはサブクエリをまったく処理しません。いくつかの主要な作業が6.0のオプティマイザーの改良に費やされ、サブクエリは現在はるかにうまく機能していますが、これらの変更は5.0または5.1シリーズに浸透していません。

于 2008-12-04T16:19:15.643 に答える