2012-01-27 13 views
1

以下のSQLクエリを実行すると、パフォーマンスは非常に遅くなります。パフォーマンスを向上させるSQL

テーブルには400,000以上の行があり、インデックスにはCheckDateというフィールドがあります。

CheckDateタイプは、それを改善する方法datetime

SELECT username, COUNT(*) AS TotalUser 
FROM table 
     WHERE DATE(CheckDate) = CURDATE() 

のですか?

+0

このクエリは遅いですか?ほぼ同じ量のデータを返す他のクエリはどうでしょうか?現在の応答時間は何ですか? – Bhushan

+1

それぞれの 'CheckDate'カラムに対して' DATE'関数を実行する必要があります。その後、 'CURDATE()'に対応するものをチェックする必要があります。それは、400,000の日付が値と比較して(そしてインデックスなしで)処理されています。 'DATE' /' CURDATE'関数を実際に効果的に使用することはありません。 –

+0

@Bhushanクエリを更新しました。 1レコードしか見つからない場合でも、結果を得るには約3秒かかります。 –

答えて

3

直接比較の代わりに範囲比較を使用してみてください。言い換えれば、それは場合に役立ちます参照してください

SELECT username, COUNT(*) AS TotalUser 
    FROM table 
    WHERE CheckDate BETWEEN CURDATE() AND ADDDATE(CURDATE(), INTERVAL 1 DAY) 

または多分

SELECT username, COUNT(*) AS TotalUser 
    FROM table 
    WHERE CheckDate >= CURDATE() AND 
     CheckDate < ADDDATE(CURDATE(), INTERVAL 1 DAY) 

としてクエリを書き直します。

EDIT: あるいは、最初のクエリは、

SELECT username, COUNT(*) AS TotalUser 
    FROM table 
    WHERE CheckDate BETWEEN CURDATE() AND 
          ADDDATE(ADDDATE(CURDATE(), INTERVAL 1 DAY), INTERVAL -1 SECOND) 

として再加工することができますが、それはむしろ醜い取得を開始し、私は負の数がINTERVAL指定子に許可されているかはわかりません。

とにかく、日付を切り捨てて別の日付と一致するかどうかを確認したいときに、より良い選択肢はしばしば遠隔比較を使用することです。より一般的には、WHERE句の中のカラム値に対する関数の使用を避けるようにしてください。

共有して楽しんでください。

+0

それはうまく動作します!ありがとう。それは現在の日付だけをチェックし、翌日はチェックしませんか? –

+0

+1:この構造を使用すると、フィルタリングされている値に対して操作を実行していません。あなたは単に「この範囲のすべての価値」と言っています。これは、オプティマイザがインデックスを使用し、関連するレコードのみを処理できることを意味します*(OPsクエリはインデックス全体のすべてのエントリをスキャンしている可能性があります)*。あなたのモデルを変更することはなく、クエリの変更のみ。 * [>]と '<'バージョンを使用して、翌日真夜中に刻印されたレコードを含めないようにする。] * – MatBailie

+0

user791022 - 上記の*は現在の日付の値のみを検索しますが、それがあなたが得ているものであることを確認してください。そうでない場合は、必要に応じて微調整してください。共有して楽しんでください。 –

1

機能インデックスは使用していません。 WHERE句には、インデックスを使用しない関数DATE()が使用されています。ダイレクトコンパレータとしてCheckDateカラムを使用してください。

これは、それが速くなることを意味するわけではありませんが、私の最初のスタートとなります。

+0

私は別のフィールドが必要だと言っていますか?例えば:CheckDate( 'DATE')とCheckTime(' TIME')? –

+0

NO!あなたの属性の周りの関数を使用しないでください。例えば、CheckDate = f1(f2(foo))のような直接属性の組み合わせを使用してください。 – Xailor

1

DATE機能のため、CheckDateフィールドのインデックスが使用されません。

列で関数を使用するたびに、その列のインデックスは使用されません。

これは、式DATE(CheckDate)を使用してテーブルに計算列を作成し、計算列にインデックスを作成することを検討する必要がある状況です(はい、DBに保持されますが、インデックスが使用されます)。

+0

ところで、フィールド上でDATE関数を実際に呼び出す必要があるかどうかは考えていませんでした。ロジックはどの機能に対しても有効です。 – Diego

関連する問題