2012-02-04 1 views
4

この質問に尋ねられていないことを願って、同様の質問を検索しようとしましたが間違ったキーワードを使用した可能性があります。とにかく、私は私が前に注文したことがないお客様のために検索する必要があり、状況に遭遇し、そのクエリは次のように実行します:が改善していない

SELECT * FROM customers 
where customers_id NOT IN (SELECT customers_id FROM orders) 

私はSELECT Sを入れ子にしていると良くないことを読んで、そうより良い選択肢は何ですか?

また、select *を入力するか、フィールドを指定する必要がありますか?また、select *の方が良いと読んでいますか?

ありがとうございます。

+0

答えを見た後、私はEXISTSの最適化について疑問を持っています。あなたはStilesCrisisとJoop Eggenのソリューションをタイムリーに見て、どれが速く走るのか見てみましょうか?おかげで –

+1

鉱山:表示行0から29(5390合計、クエリは0.0155秒かかりました) StilesCrisis:表示行0から29(5390合計、クエリは0.0090秒かかりました) ジョープEggen:表示行0から29(5390総計、クエリは0.0039秒かかりました) 注:私はそれぞれを1度だけ実行しましたが、平均時間を正しく取得するにはさらに多くの時間を実行する必要があります。また、Joopのものについては、SELECT *を使用して、特定のフィールドを選択すると改善できるかどうか疑問に思っています。 – mr1031011

+1

複数回実行した後、信じられないかもしれません。 – mr1031011

答えて

5
SELECT * FROM customers 
LEFT JOIN orders ON customers.customers_id = orders.customers_id 
WHERE orders.customers_id IS NULL 
+0

親愛なるStilesCrisis、答えをありがとう、非常に興味深い解決策、それは決して考えなかった – mr1031011

2

簡単な質問:SELECT *は、一部のフィールドを選択するよりも高価である、それも劇的にすることができます。索引内のすべてのフィールドが少ない場合はデータが少なく、表へのアクセスはありません。データベースフィールド値からプログラミング言語変数へのマーシャリングはありません。

ネストされたサブクエリとジョイントには、その権利があります。

SELECT * FROM customers where customers_id NOT IN (SELECT customers_id FROM orders) 

のように書き換えることができます。

SELECT * 
FROM customers c 
WHERE NOT EXISTS(SELECT * 
       FROM orders o 
       WHERE o.customers_id = c.customers_id) 

MySQLは、それが良いように再帰的に今の選択を最適化することc.customers_idについての情報を持っているEXISTS最適化することができると述べています。

@StilesCrisisのJOINは最高ですが、私は疑いがありますが正しいです。 (私は一日のうちにコーヒーを飲みませんでした。)

BTW。 EXISTS(SELECT *は、実際にはすべてのフィールドのためのスペースを予約しておらず、大丈夫です。

+1

なぜあなたが 'JOIN'を疑うか分からない。それは本当に複雑ではありません。 – StilesCrisis

+0

customers_idに** join **がありますが、このような一致が存在しない顧客が必要です。ヌルチェックはそれに影響しません。それは...ですか?いいですね。 –

+0

@StilesCrisisは 'SELECT DISTINCT'でしょうか?あなたのパターンを使用したことはありませんが、同じような左のジョイントは必要です。 –

関連する問題