0

注文履歴 (ltv) の合計とともに、可能な顧客のリストを取得しようとしています。

order by を指定しないと、このクエリは 1 秒以内に読み込まれます。とクエリを使用するorder byと、90 秒以上かかります。

SELECT a.customerid,a.firstname,a.lastname,Orders.ltv  
    FROM customers a
    LEFT JOIN (
        SELECT customerid,
               SUM(amount) as ltv 
        FROM orders 
       GROUP BY customerid) Orders 
     ON Orders.customerid=a.customerid  
ORDER BY 
   Orders.ltv DESC 
LIMIT 0,10

これをスピードアップする方法はありますか?

編集:クエリを少しクリーンアップしすぎたと思います。クエリは、実際にはこのバージョンよりも少し複雑です。その他のデータは顧客テーブルから選択され、同様に並べ替えることができます。

4

3 に答える 3

4

実際のスキーマがないと、データがどのように関連しているかを知るのは少し難しいですが、このクエリは同等で、よりパフォーマンスが高いはずです。

SELECT a.customerid, coalesce(sum(o.amount), 0) TotalLtv FROM customers a
LEFT JOIN orders o ON a.customerid = o.cusomterid
GROUP BY a.customerid
ORDER BY TotalLtv DESC
LIMIT 10

ご注文のないお客様には必ずcoalesceお返しいたします。0

@ypercube が私に気づいたように、上のインデックスamountも役に立ちません。あなたはそれを試すことができます:

ALTER TABLE orders ADD INDEX(customer, amount)

質問の更新後

select 句に機能的に依存するフィールドをさらに追加する必要がある場合a.customeridは、非標準の MySQLgroup by句を使用できます。これにより、次によるグループ化よりもパフォーマンスが向上しますa.customerid, a.firstname, a.lastname

SELECT a.customerid, a.firstname, a.lastname, coalesce(sum(o.amount), 0) TotalLtv
FROM customers a
LEFT JOIN orders o ON a.customerid = o.cusomterid
GROUP BY a.customerid
ORDER BY TotalLtv DESC
LIMIT 10
于 2013-10-21T19:37:48.640 に答える
0

2つのこと。まず、内部クエリを使用しないでください。MySQL では、プロジェクション エイリアスで ORDER BY を使用できます。次に、構成されたキー (customerid、amount) に B-TREE インデックスを作成することで、かなりの改善が得られるはずです。その後、エンジンは、行データをフェッチすることなく、インデックスを単純にトラバーサルすることで、このクエリを実行できます。

于 2013-10-21T19:48:32.767 に答える