2つの異なるクエリがあります。しかし、それらは両方とも同じテーブルにあり、両方とも同じWHERE
句を持っています。したがって、彼らは同じ行を選択しています。
クエリ1:
SELECT HOUR(timestamp), COUNT(*) as hits
FROM hits_table
WHERE timestamp >= CURDATE()
GROUP BY HOUR(timestamp)
クエリ2:
SELECT country, COUNT(*) as hits
FROM hits_table
WHERE timestamp >= CURDATE()
GROUP BY country
どうすればこれをより効率的にすることができますか?
このテーブルに正しくインデックスが付けられていれば、今日の行だけを見ているので、テーブル全体の大きさは正直問題ではありません。
テーブルのインデックスが正しくない場合、何をしてもこれらのクエリのパフォーマンスはひどいものになります。
あなたのWHERE timestamp >= CURDATE()
句を使用すると、上のインデックス持っている必要があります意味timestamp
の列を。クエリの1つで、GROUP BY country
インデックスをカバーする複合語(timestamp, country)
が非常に役立つことが示されています。
したがって、単一の複合インデックス(timestamp, country)
は、質問の両方のクエリを満たします。
それがどのように機能するかを説明しましょう。今日のレコード(または特定のtimestamp
値で開始および終了するレコード)を検索し、国ごとにグループ化してカウントするために、MySQLは次の手順を実行することでクエリを満たすことができます。
timestamp
。O(log n)。country
値を取得します。country
値までスキャンします。オン)。timestamp
範囲が終了するまで手順3を繰り返します。このインデックススキャン操作は、エース開発者のチーム(MySQLチーム)が10年のハードワークで実現できるのとほぼ同じ速さです。(土曜日の午後にはそれらを上回ることができない場合があります。)MySQLは、インデックスの小さなサブセットでクエリ全体を満たします。したがって、背後にあるテーブルの大きさは実際には問題ではありません。
これらのクエリの1つを次々に実行すると、MySQLの一部またはすべてのインデックスデータブロックがRAMキャッシュに残っている可能性があるため、ディスクからそれらを再フェッチする必要がない場合があります。それはさらに役立ちます。
サンプルクエリがどのようにつながるかわかりますtimestamp
か?最も重要なWHERE
基準は、タイムスタンプの範囲を選択します。そのため、私が提案した複合インデックスのtimestamp
最初の列があります。country
その列の単純なインデックスにつながるクエリがない場合は、おそらく役に立たないでしょう。
あなたは本当に複合カバーインデックスが必要かどうか尋ねました。あなたは、おそらく必要があります読ん について どのように彼らは仕事と自分のためにその決定を下します。
インデックスの選択には明らかにトレードオフがあります。各指標は、プロセス減速INSERT
とUPDATE
少し、そして多くのクエリをスピードアップすることができます。特定のアプリケーションのトレードオフを整理できるのはあなただけです。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加