以下の方法で、ログのクエリと分析を高速化できます。
シャード数の増加または専用 SQL の有効化
シャード数を増やすことで、データの読み書き能力を向上させることができます。ただし、この方法は増分データに対してのみ有効です。シャードはコンピューティングリソースであり、計算速度はシャード数に比例して向上します。シャードあたりのスキャンデータ数が 5,000 万件を超えないようにしてください。シャードを分割することで、シャード数を増やすことができます。詳細については、「シャードの分割」をご参照ください。シャードの課金に関する詳細については、「課金方法に基づくアクティブなシャードの課金例」をご参照ください。
専用 SQL は、より高い分析の同時実行性と、より大規模なデータスキャンをサポートします。
時間範囲の短縮とクエリ操作のデータ量の削減
時間範囲が長いと、クエリ操作が遅くなります。
計算速度を上げたい場合は、クエリ操作の時間範囲を短縮します。
データ量が多いと、クエリ操作が遅くなります。
クエリ操作のデータ量を減らすことを推奨します。
クエリの繰り返し
クエリ結果が不正確な場合は、データを繰り返しクエリできます。クエリ操作を実行するたびに、基盤となるアクセラレーションメカニズムが既存のクエリ結果を分析します。データを繰り返しクエリすると、システムはより正確な結果を返すことができます。
分析文の最適化
時間のかかるクエリ文には、次のような特徴があります:
`GROUP BY` 句を使用して、1 つ以上の文字列型の列に基づいて分析結果をグループ化している。
`GROUP BY` 句を使用して、5 つ以上の列に基づいて分析結果をグループ化している。
文に文字列を生成する操作が含まれている。
以下の方法で分析文を最適化できます:
文字列を生成する操作を含めない。
たとえば、`date_format` 関数を使用して指定されたフォーマットのタイムスタンプを生成すると、クエリ効率が低くなります。`date_trunc` 関数または `time_series` 関数を使用してタイムスタンプを生成することを推奨します。例:
* | select date_format(from_unixtime(__time__) , '%H_%i') as t, count(1) group by t1 つ以上の文字列型の列に基づいて分析結果をグループ化しない。
たとえば、`GROUP BY` 句を使用して 1 つ以上の文字列型の列に基づいて分析結果をグループ化すると、ハッシュ計算のワークロードが重くなります。ハッシュ計算のワークロードは、計算全体のワークロードの 50% 以上を占めます。例:
効率的なクエリ文
* | select count(1) as pv , from_unixtime(__time__-__time__%3600) as time group by __time__-__time__%3600非効率的なクエリ文
* | select count(1) as pv , date_trunc('hour',__time__) as time group by time
この 2 つのクエリ文は、1 時間あたりのログ数を計算するために使用されます。2 番目の文では、タイムスタンプが文字列に変換され、その文字列に基づいて分析結果がグループ化されます。たとえば、「2021-12-12 00:00:00」は文字列形式のタイムスタンプです。最初の文では、正時のタイムスタンプが取得され、そのタイムスタンプに基づいて分析結果がグループ化された後、タイムスタンプが文字列に変換されます。
複数の列に基づいて分析結果をグループ化する場合は、値の数が多いフィールドを値の数が少ないフィールドの前に配置することを推奨します。
たとえば、特定のフィールドの値の数が 13 で、uid フィールドの値の数が 1 億である場合、`GROUP BY` 句では uid フィールドを特定のフィールドの前に配置することを推奨します。例:
効率的なクエリ文
* | select province,uid,count(1) group by uid,province非効率的なクエリ文
* | select province,uid,count(1) group by province,uid
近似関数を使用する。
近似関数のパフォーマンスは、精度が指定された関数よりも優れています。近似関数は、速度のために精度を犠牲にします。例:
効率的なクエリ文
* |select approx_distinct(ip)非効率的なクエリ文
* | select count(distinct(ip))
低カーディナリティのシナリオで複数の DISTINCT 集計関数を使用する。
複数の `DISTINCT` 操作では生データを複数回コピーする必要があり、高いネットワークオーバーヘッドが発生します。これを最適化するには、
enable_opt_distinct_aggsセッションスイッチを有効にします。例:効率的なクエリ・分析文
* | select count(1), count(distinct projectId), count(distinct logstore) from log非効率的なクエリ・分析文
* | set session enable_opt_distinct_aggs=true; select count(1), count(distinct projectId), count(distinct logstore) from log
分析文ではクエリしたい列のみを指定し、すべての列をクエリしない。
分析文では、計算に必要な列のみをクエリすることを推奨します。すべての列をクエリしたい場合は、検索構文を使用してください。例:
効率的なクエリ文
* |select a,b c非効率的なクエリ文
* |select *
グループ化に使用しない列を集計関数に配置する。
たとえば、`userid` 列と `username` 列の値は一致している必要があります。データをグループ化するには、`GROUP BY` 句で `userid` 列を指定するだけで十分です。例:
効率的なクエリ文
* | select userid, arbitrary(username), count(1) group by userid非効率的なクエリ文
* | select userid, username, count(1) group by userid,username
`IN` 句を使用しない。
分析文では `IN` 句を使用しないことを推奨します。検索文で `OR` 句を使用できます。例:
高速なクエリ・分析文
key: a or key: b or key: c | select count(1)非効率的なクエリ文
* | select count(1) where key in ('a','b')