顧客がリストされている製品と一緒に購入したもののクエリ
質問
頭を包むことができない非常に古いクエリを最適化しようとしています。私がアーカイブしたいのは、他の顧客が興味を示したもの、つまり訪問者が見ている製品と一緒に購入したものを示すものをウェブショップで訪問者に推薦したいということです。
私はサブクエリを持っていますが、そうです 非常に ゆっくりと、約8 000 000行で約15秒かかります。
レイアウトは、ユーザーバスケットに入れられるすべての製品がテーブルに保管されていることです wsBasket
そしてaによって分離されます basketid
(別のテーブルではメンバーに関連付けられています)。
この例では、ユーザーがProductID 427と一緒に購入した最も人気のあるすべての製品をリストしたいが、ProductID 427自体はリストしません。
SELECT productid, SUM(quantity) AS qty
FROM wsBasket
WHERE basketid IN
(SELECT basketid
FROM wsBasket
WHERE productid=427) AND productid!=427
GROUP by productid
ORDER BY qty
DESC LIMIT 0,4;
どんな助けも大歓迎です!これが少なくとも誰かにまったく理にかなっていることを願っています:)
更新1:コメントありがとうございます。ここに人が私の答えです、彼らはコメントフィールドに収まりませんでした。
上記のクエリで説明を使用して、私はfllowingを得ました。注意してください、私はテーブルにインデックスがありません(上の主キーを除く id
-field)、透けて透けて塗るためにクエリを変更し、適切なキーにインデックスを配置し、インデックスを配置したいと考えています。
+----+--------------------+----------+------+---------------+------+---------+------+------+----------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+--------------------+----------+------+---------------+------+---------+------+------+----------------------------------------------+
| 1 | PRIMARY | wsBasket | ALL | NULL | NULL | NULL | NULL | 2821 | Using where; Using temporary; Using filesort |
| 2 | DEPENDENT SUBQUERY | wsBasket | ALL | NULL | NULL | NULL | NULL | 2821 | Using where |
+----+--------------------+----------+------+---------------+------+---------+------+------+----------------------------------------------+
解決
追加する2つの明白なインデックス:1つはBasketIDに、2番目のProductID:クエリを再試行して、インデックスが使用されていることを確認するために新しい説明
他のヒント
適切なインデックスが存在することを保証します productid
と basketid
, 、特にMySQLでは、サブクエリではなく、単純な結合としてクエリを構築することで、多くの場合、クエリを構築することから恩恵を受けることがよくあります。
SELECT b1.productid, SUM(b1.quantity) AS qty
FROM wsBasket AS b0
JOIN wsBasket AS b1 ON b1.basketid=b0.basketid
WHERE b0.productid=427 AND b1.productid<>427
GROUP BY b1.productid
ORDER BY qty DESC
LIMIT 4
私にとって、類似の可能性のあるデータセットでは、結合は2つになりました select_type: SIMPLE
の行 EXPLAIN
一方、サブクエリ法は恐ろしいパフォーマンスを吐き出します DEPENDENT SUBQUERY
. 。その結果、結合は数桁以上速くなりました。
主にこのクエリで検索するために使用する2つのフィールドは、ProductIDとBasketIDです。
ProductIDが427に等しいレコードを検索すると、データベースにはこのレコードを見つける場所がわかりません。一致するものが1つ、別のマッチングのものがないことがわからないので、テーブル全体、潜在的に数千のレコードを調べる必要があることさえ知らない。
インデックスは、ソートされた別のファイルであり、並べ替えに興味があるフィールドのみが含まれています。したがって、インデックスを作成すると、大量の時間を節約できます!