2017-01-13 4 views
0

基本的に私はユーザーの興味に基づいて「提案」ページ​​を作成しようとしています。同じテーブル内のMySQLサブクエリがパフォーマンスを殺します

累積テーブルには、すべてのユーザーが見たすべての製品が格納されています。私の考えは、私が見た製品を訪問したすべての人のすべての見た製品を選択することでした。私はしばらく今のクエリを思い付くしようとしてきたが、私の最高のアイデアが

  • a)のほとんどのクエリ
  • b)はサブクエリ

事があるが起こっていた、私はそれをやって思いますテーブルが大きくなると、スケーラビリティがないクエリはほとんどありません。サブクエリを使用すると、EXPLAINを使用した場合でも、すべてのデータが正常に見えたにもかかわらず、データベースを破壊したクエリがあった(まだ一時テーブルがなく、ディスクヒットしない)行。クエリを1つずつ実行すると、1秒未満で私が望むことができたので、私は本当に困惑しています。私はどこでミスをしていますか?

テーブルには、次の列のID(PRIMARY)、USER_ID、PRODUCT_ID、以下の不要なフィールド

の束私が思い付いたSQLクエリがあるがあり

SELECT product_id 
FROM user_behavior 
WHERE user_id 
IN (

    SELECT user_id 
    FROM user_behavior 
    WHERE user_id <> 43456 
    AND product_id 
    IN (

     SELECT product_id 
     FROM user_behavior 
     WHERE user_id =43456 
     GROUP BY product_id 
    ) 
    AND offer_city_id 
    IN (0, 2) 
) 

(それは私のサーバーを殺します)申し訳ありませんが、私はテーブルを視覚化することはできません:(

:私は返します次

| id | select_type   | table    | type    | possible_keys   | key  | key_len | ref  | rows  | Extra      | 
|---- |-------------------- |--------------- |---------------- |------------------- |--------- |--------- |------- |------- |-------------------------- | 
| 1  | PRIMARY    | user_behavior  | index    | NULL     | user_id | 8   | NULL  | 25800  | Using where; using index | 
| 2  | DEPENDENT SUBQUERY | user_behavior  | index_subquery | user_id,user_id_2  | user_id | 4   | func  | 3   | Using where    | 
| 3  | DEPENDENT SUBQUERY | user_behavior  | ref    | user_id,user_id_2  | user_id | 4   | const  | 76  | Using where; using index | 

EDITを説明し実行している言ったように

答えて

1

IN (SELECT ...)を使用しないでください。

私はクエリが何をしようとしているのかかなり失われていますが、JOINEXISTSに切り替えることは、このソリューションの一部になる可能性があります。おそらく、これに近いもの:

SELECT s.product_id 
    FROM user_behavior AS a 
    JOIN user_behavior AS b ON b.user_id = a.user_id 
    WHERE EXISTS (
       SELECT * 
        FROM user_behavior 
        WHERE product_id = b.product_id 
        AND user_id = 43456 
       ) 
     AND b.offer_city_id IN (0, 2) 
     AND b.user_id <> 43456 

そして含まINDEX(user_id, product_id)多分これだけが必要な?? ...

(順序のいずれかの場合)または '複合'

SELECT DISTINCT product_id 
    FROM user_behavior AS b 
    WHERE EXISTS (
       SELECT * 
        FROM user_behavior 
        WHERE product_id = b.product_id 
        AND user_id = 43456 
       ) 
     AND offer_city_id IN (0, 2) 
     AND user_id <> 43456 

まあ、Iあなたがこれらの試みからいくつかのアイデアを得ることを望みます。

+0

2番目のクエリは、まさに私が必要としたものでした。 EXISTSがどのように動作しているのかわかりませんが、私はMySQLのドキュメントに目を向けて、それを把握しようとします。ありがとうございました! – Sk1ppeR

+0

'EXISTS'は' JOIN'と似ているという点で「セミジョイン」ですが、マッチすると停止します。 TrueまたはFalseのみを返します。 '*'によって誤解されることはありません。 –

関連する問題