このページでは、クエリを最適化してクエリの効率を向上させる方法について説明します。 次の方法によって、 TSL モデルを取得できます。
- シャードを追加します。
- クエリの時間範囲とデータ量を減らします。
- クエリを複数回繰り返します。
- クエリの SQL ステートメントを最適化します。
シャードの追加
シャードが多いほど、計算リソースが増え、計算が高速化します。 シャードを追加して、各シャードでスキャンされるログの数が平均で 5,000 万を超えないようにすることができます。
シャードを分割 してシャードを追加できます。
注 シャードを分割すると料金が上がり、新しいデータのクエリのみが加速されます。 古いデータは古いシャードに保存されたままです。
クエリの時間範囲とデータ量の削減
- 時間範囲が大きいほど、クエリは遅くなります。 1 年または 1 か月以内にデータをクエリする場合、データは日ごとに計算されます。 したがって、時間を短縮すると計算が高速化できます。
- データ量が多いほど、クエリは遅くなります。 クエリ対象のデータ量をできるだけ減らします。
クエリの繰り返し操作
クエリの結果が不正確である場合、クエリを複数回繰り返すことができます。 各クエリ中に、基礎となるアクセラレーションメカニズムは、分析のために以前のクエリ結果を最大限に活用します。 したがって、複数のクエリを使用すると、クエリ結果がより正確になります。
クエリ用 SQL 文の最適化
時間のかかるクエリ文には、次の特性があります。
- 文字列の列で GROUP BY を実行します。
- 5 列以上のフィールドで GROUP BY を実行します。
- 文字列を生成する操作が含まれます。
- 文字列を生成する操作をできるだけ避ける
- date_format 関数を使用して書式設定されたタイムスタンプを生成すると、クエリ効率が低下します。
* | select date_format(from_unixtime(__time__) , '%H_%i') as t, count(1) group by t
- substr() method メソッドを使用すると、文字列が生成されます。 date_trunc または time_series 関数を使用してタイムスタンプを分析することを推奨します。
- date_format 関数を使用して書式設定されたタイムスタンプを生成すると、クエリ効率が低下します。
- 文字列での Group By をできる限り実行しないようにするGroup By を文字列で実行すると、通常計算全体の 50 %以上に及ぶ大量のハッシュ計算が行われます。 例:
クエリ 1 とクエリ 2 の両方とも、1 時間ごとにログカウント値を計算します。 ただし、クエリ 1 は、時刻を文字列 (2017-12-12 00:00:00など) に変換し、この文字列に対して GROUP BY を実行します。 クエリ 2 は、時間ごとの時間値を計算し、結果に対してGROUP BYを実行してから、値を文字列に変換します。 クエリ 1 は前者は文字列をハッシュする必要があるため、クエリ 2 よりも効率性が落ちます。* | select count(1) as pv , date_trunc('hour',__time__) as time group by time * | select count(1) as pv , from_unixtime(__time__-__time__%3600) as time group by __time__-__time__%3600
- 複数の列で GROUP BY を実行する場合、頭文字に基づいてアルファベット順にフィールドをリストします。たとえば、13 の州には 1 億人のユーザーがいます。
Fast: * | select province,uid,count(1)groupby province,uid Slow: * | select province,uid,count(1)groupby uid,province
- 推定関数を使用します。推定関数は、正確な計算よりもはるかに優れたパフォーマンスを提供します。 推定により、許容範囲内で精度を犠牲にすることにより、高速計算が実現されます。
Fast: * | select approx_distinct(ip) Slow: * | select count(distinct(ip))
- SQL 文で必要な列のみを取得し、すべての列の読み取りはできるだけ避けるようにします。クエリログを使用してすべての列を取得します。 計算を加速するには、可能な場合は SQL で必要な列のみを取得します。
Fast: * |select a,b c Slow: * |select *
- 可能であれば、集約関数に非 GROUP BY 列を配置します。たとえば、ユーザー ID はユーザー名と完全に一致します。 したがって、ユーザー ID とユーザー名の両方ではなく、ユーザー ID のみで GROUP BY を実行してください。
Fast: * | select userid, arbitrary(username), count(1)groupby userid Slow: * | select userid, username, count(1)groupby userid,username
- 可能であれば、IN 演算子の使用を避けてください。可能であれば、SQL 文で IN 演算子を使用しないでください。 代わりに、OR 演算子を使用してください。
Fast: key : a or key :b or key:c | select count(1) Slow: * | select count(1) where key in ('a','b')