0

60万を超えるレコードで実行されるmysqlSUMクエリがあります。私が今していることはこんな感じです

 SELECT SUM (payment)
    FROM payment_table
    WHERE
       payment_date BETWEEN ... AND ...
       AND
       payment_status = 'paid'

レコードセットを減らすためにクエリをこの形式に変更しましたが、それでもほぼ同じ時間がかかります。

SELECT SUM(Payments)
FROM (
    SELECT payment AS Payments FROM payment_table WHERE
     payment_date BETWEEN DATE_FORMAT(NOW(), '2012-2-01') AND DATE_FORMAT(LAST_DAY(DATE_FORMAT(NOW(), '2012-2-01')), '%Y-%m-%d')
    AND
    payment_status = 'paid'
) AS tmp_table

この合計クエリを最適化する方法はありますか。編集:

これは、クエリがで実行されたときの結果ですEXPLAIN

` (IDに挿入,select_type,テーブル,タイプ,possible_keyskeykey_len ref rows , Extra` )values( '1'、'SIMPLE'、'lps'、'index_merge'、'assigned_user_id、scheduled_pa​​yment_date、payment_status、deleted'、'deleted、assigned_user_id、payment_status' ,、'2,109,303'、NULL、 '23347'、'intersect(deleted、assigned_user_id、payment_status);を使用して');,,,

4

1 に答える 1

1

述語のデータ型を列と一致させる必要があります。payment_typeisであるためDATE、BETWEEN 値DATEも次のようにします。

 WHERE payment_date BETWEEN
     CURDATE() AND LAST_DAY(CURDATE())

タイプが一致すると、インデックスが確実に使用されます。


対照的に、クエリはテキストDATE_FORMAT()データ型を生成するを使用しているため、比較を実行するために、mysql は列をテキストに変換しているため、インデックスを使用できません (インデックスにはテキスト値ではなく値が含まれます)。そのため、すべての行が変換および比較されます。payment_dareDATE


上記の変更を行った後もパフォーマンスの問題が発生する場合は、次を実行します。

ANALYZE TABLE payment_table;

これにより、インデックス付きの列の値の分布がチェックされ、mysql が正しいインデックスを選択するのに役立ちます。

于 2013-03-11T11:40:26.017 に答える