0

MySQLでINを使用した場合、パフォーマンスが向上したことは一度もありません。また、パフォーマンスの問題が発生しました。

ビューを作成しようとしています。その関連部分は次のとおりです。

SELECT
  c.customer_id,
  ....
  IF (c.customer_id IN (
            SELECT cn.customer_id FROM customer_notes cn
        ), 1, 0) AS has_notes
  FROM customers c;

基本的には、お客様にメモが付いているかどうかを知りたいだけです。ノートの数は関係ありません。JOINを使用してこれを書き換えて高速化するにはどうすればよいですか?

顧客テーブルには現在150万行あるため、パフォーマンスが問題になります。

4

3 に答える 3

1

またはEXISTSよりもあなたの状況に適していると思います。JOININ

SELECT 
   IF (EXISTS ( 
        SELECT *
        FROM customer_notes cn 
        WHERE c.customer_id = cn.customer_id),
       1, 0) AS filter_notes 
FROM customers 
于 2010-12-16T23:27:49.727 に答える
1

顧客IDを選択する必要はありませんか?現状では、サブクエリを顧客ごとに1回実行し、どちらがどの顧客に適用されるかわからない真または偽の値のストリームを取得していませんか?

それが必要な場合は、customersテーブルを参照する必要はありません(データベースをセマンティック崩壊の状態に保ち、対応する顧客がないcustomer_notesにエントリがある可能性がある場合を除きますが、より大きな問題があります)このクエリのパフォーマンスよりも); 簡単に使用できます:

SELECT DISTINCT Customer_ID
  FROM Customer_Notes
 ORDER BY Customer_ID;

Customer_Notesテーブルに少なくとも1つのエントリがある顧客ID値のリストを取得します。

顧客ID値と関連するtrue/false値のリストが必要な場合は、結合を行う必要があります。

SELECT C.Customer_ID,
       CASE WHEN N.Have_Notes IS NULL THEN 0 ELSE 1 END AS Has_Notes
  FROM Customers AS C
  LEFT JOIN (SELECT Customer_ID, COUNT(*) AS Have_Notes 
               FROM Customer_Notes
              GROUP BY Customer_ID) AS N
    ON C.Customer_ID = N.Customer_ID
 ORDER BY C.Customer_ID;

これでパフォーマンスが低下する場合は、Customer_Notes.Customer_IDにインデックスがあることを確認してください。それが問題ではない場合は、クエリプランを調べてください。


できない...ビューで

ビューで許可されるものに対するささいな制限は、どのDBMSでも常に厄介です(制限があるのはMySQLだけではありません)。ただし、1回の通常の結合でそれを行うことができます。ただ今思い出した。 COUNT(column)null以外の値のみをカウントし、すべての値がnullの場合は0を返すため、0または1だけでなくカウントを取得してもかまわない場合は、次を使用できます。

SELECT C.Customer_ID,
       COUNT(N.Customer_ID) AS Num_Notes
  FROM Customers AS C
  LEFT JOIN Customer_Notes AS N
    ON C.Customer_ID = N.Customer_ID
 GROUP BY C.Customer_ID
 ORDER BY C.Customer_ID;

そして、絶対に0または1が必要な場合。

SELECT C.Customer_ID,
       CASE WHEN COUNT(N.Customer_ID) = 0 THEN 0 ELSE 1 END AS Has_Notes
  FROM Customers AS C
  LEFT JOIN Customer_Notes AS N
    ON C.Customer_ID = N.Customer_ID
 GROUP BY C.Customer_ID
 ORDER BY C.Customer_ID;

'N.Customer_ID'の使用は重要であることに注意してください-テーブル内のどの列でも使用できますが(ただし、他の列の名前は明かしていません、AFAICR)、通常は結合列以外のものを使用します明快さ。

于 2010-12-16T23:44:31.953 に答える
0

これを試して

SELECT
  CASE WHEN cn.customer_id IS NOT NULL THEN 1
        ELSE 0
    END     AS filter_notes
  FROM customers c LEFT JOIN customer_notes cn
    ON c.customer_id= cn.customer_id
于 2010-12-16T23:29:17.950 に答える