このページでは、データベースのホットスポットを検出してデバッグする方法について説明します。スプリット内のホットスポットに関する統計情報には、GoogleSQL と PostgreSQL の両方でアクセスできます。
Spanner は、テーブルとインデックスの主キーで並べ替えられた連続したキースペースとしてデータを保存します。スプリットは、一連のテーブルまたはインデックスの行の範囲です。スプリットの開始点は、スプリット スタートと呼ばれます。スプリット リミットは、スプリットの終了を設定します。スプリットにはスプリット スタートが含まれますが、スプリット リミットは含まれません。
Spanner でのホットスポットとは、同じサーバーに多くのリクエストが送信され、サーバーのリソースが飽和状態になり、遅延が大きくなる可能性がある状況を指します。ホットスポットの影響を受けるスプリットは、ホット スプリットまたはウォーム スプリットと呼ばれます。
スプリットのホットスポット統計情報(システムでは CPU_USAGE_SCORE として識別されます)は、サーバー上で使用可能なリソースによって制約されるスプリットの負荷の測定値です。この測定値はパーセンテージで示されます。スプリットの負荷の 50% 以上が使用可能なリソースによって制約されている場合、そのスプリットはウォームと見なされます。スプリットの負荷の 100% が制約されている場合、そのスプリットはホットと見なされます。このようなホット分割は、提供されるリクエストのレイテンシにも影響する可能性があります。
分割の CPU_USAGE_SCORE は、分割にアクセスするワークロードと分割境界の変更に基づいて、一定のままにすることも、時間とともに変化させることもできます。
Spanner は、ウォーム スプリットとホット スプリットのリソース制約に基づいて、負荷ベースの分割を使用して、キー空間全体に負荷を均等に分散することがあります。ウォーム スプリットとホット スプリットは、ロード バランシングのためにインスタンスのサーバー間で移動できます。Spanner はバックグラウンドで負荷ベースの分割を実行するため、レイテンシへの影響を最小限に抑えることができます。ただし、アプリケーションのアンチパターンが原因で、分割を複数回試行しても、Spanner が負荷を分散できない場合があります。そのため、ウォーム スプリットまたはホット スプリットの状態が 10 分以上続く場合は、さらにトラブルシューティングを行い、アプリケーションの変更が必要になる可能性があります。
Spanner のホット スプリットの統計情報は、ホットスポットが発生しているスプリットの特定に役立ちます。その後、必要に応じてアプリケーションまたはスキーマを変更できます。この統計情報は、SQL ステートメントを使用して SPANNER_SYS.SPLIT_STATS_TOP_MINUTE システム テーブルから取得できます。
ホット スプリットの統計情報にアクセスする
Spanner は、SPANNER_SYS スキーマにホット スプリットの統計情報を提供します。SPANNER_SYS データは、GoogleSQL インターフェースと PostgreSQL インターフェースを介してのみ使用できます。このデータには次の方法でアクセスします。
- Google Cloud コンソール(データベースの Spanner Studio ページ)。
- gcloud spanner databases execute-sqlコマンド。
- executeSqlメソッドまたは- executeStreamingSqlメソッド。
Spanner が提供する次の単一読み取りメソッドは、SPANNER_SYS をサポートしていません。
- 強力な読み取りを実行してテーブルから単一行または複数行を読み取る。
- ステイル読み取りを実行してテーブルから単一行または複数行を読み取る。
- セカンダリ インデックスから単一行または複数行を読み取る。
ホット スプリットの統計情報
ホット スプリットを追跡するには、次のテーブルを使用します。
- SPANNER_SYS.SPLIT_STATS_TOP_MINUTE: 1 分間隔でホット スプリットを示します。
これらのテーブルには以下のプロパティがあります。
- 各テーブルには、テーブル名に示されている期間で間隔が重複していないデータが含まれています。
- 時間間隔は時刻に基づきます。 - 分が終わる際に 1 分の間隔が終了します。
 
- 各間隔が経過すると、Spanner はすべてのサーバーからデータを収集し、その後すぐに - SPANNER_SYSテーブルでデータを使用できるようにします。- たとえば、午前 11 時 59 分 30 秒に SQL クエリで使用可能な最新の時間間隔は次のとおりです。 - 1 分: 午前 11 時 58 分 00 秒~午前 11 時 58 分 59 秒
 
- Spanner は統計情報をスプリットごとにグループ化します。 
- 各行には、指定された期間中に Spanner が統計情報をキャプチャした各スプリットのホットまたはウォームの度合いを示すパーセンテージが含まれています。 
- 使用可能なリソースによって制約されているスプリットの負荷が 50% 未満の場合、Spanner は統計情報をキャプチャしません。期間中にホット スプリットのすべてを保存できない場合、システムは指定された期間中に - CPU_USAGE_SCOREの割合が最も高いスプリットを優先します。スプリットが返されない場合、ホットスポットがないことを意味します。
テーブル スキーマ
次の表に、統計情報のテーブル スキーマを示します。
- SPANNER_SYS.SPLIT_STATS_TOP_MINUTE
| 列名 | タイプ | 説明 | 
|---|---|---|
| INTERVAL_END | TIMESTAMP | スプリットがホットであった期間の終了 | 
| SPLIT_START | STRING | スプリットの行範囲の開始キー。スプリット スタートは <begin>の場合もあります。これはキースペースの開始を示します。 | 
| SPLIT_LIMIT | STRING | スプリットの行範囲のリミットキーです。リミット: キーは <end>で、キースペースの終了を示します。 | 
| CPU_USAGE_SCORE | INT64 | スプリットの CPU_USAGE_SCOREのパーセンテージ。CPU_USAGE_SCOREのパーセンテージが 50% の場合、ウォームまたはホット スプリットが存在することを示します。 | 
| AFFECTED_TABLES | STRING ARRAY | スプリットに行が格納される可能性のあるテーブル。 | 
スプリット スタート キーとスプリット リミット キー
スプリットはデータベースの連続した行範囲であり、スタートキーとリミットキーで定義されます。スプリットは、単一の行、狭い行範囲、広い行範囲にできます。また、スプリットには複数のテーブルまたはインデックスを含めることができます。
SPLIT_START 列と SPLIT_LIMIT 列は、ウォーム スプリットまたはホット スプリットの主キーを識別します。
サンプル スキーマ
以下に、このページのトピックのサンプル テーブルのスキーマを示します。
GoogleSQL
CREATE TABLE Users (
  UserId INT64 NOT NULL,
  FirstName STRING(MAX),
  LastName STRING(MAX),
) PRIMARY KEY(UserId);
CREATE INDEX UsersByFirstName ON Users(FirstName DESC);
CREATE TABLE Threads (
  UserId INT64 NOT NULL,
  ThreadId INT64 NOT NULL,
  Starred BOOL,
) PRIMARY KEY(UserId, ThreadId),
  INTERLEAVE IN PARENT Users ON DELETE CASCADE;
CREATE TABLE Messages (
  UserId INT64 NOT NULL,
  ThreadId INT64 NOT NULL,
  MessageId INT64 NOT NULL,
  Subject STRING(MAX),
  Body STRING(MAX),
) PRIMARY KEY(UserId, ThreadId, MessageId),
  INTERLEAVE IN PARENT Threads ON DELETE CASCADE;
CREATE INDEX MessagesIdx ON Messages(UserId, ThreadId, Subject),
INTERLEAVE IN Threads;
PostgreSQL
CREATE TABLE users
(
   userid    BIGINT NOT NULL PRIMARY KEY,-- INT64 to BIGINT
   firstname VARCHAR(max),-- STRING(MAX) to VARCHAR(MAX)
   lastname  VARCHAR(max)
);
CREATE INDEX usersbyfirstname
  ON users(firstname DESC);
CREATE TABLE threads
  (
    userid   BIGINT NOT NULL,
    threadid BIGINT NOT NULL,
    starred  BOOLEAN, -- BOOL to BOOLEAN
    PRIMARY KEY (userid, threadid),
    CONSTRAINT fk_threads_user FOREIGN KEY (userid) REFERENCES users(userid) ON
    DELETE CASCADE -- Interleave to Foreign Key constraint
  );
CREATE TABLE messages
  (
    userid    BIGINT NOT NULL,
    threadid  BIGINT NOT NULL,
    messageid BIGINT NOT NULL PRIMARY KEY,
    subject   VARCHAR(max),
    body      VARCHAR(max),
    CONSTRAINT fk_messages_thread FOREIGN KEY (userid, threadid) REFERENCES
    threads(userid, threadid) ON DELETE CASCADE
  -- Interleave to Foreign Key constraint
  );
CREATE INDEX messagesidx ON messages(userid, threadid, subject), REFERENCES
threads(userid, threadid);
キースペースが次のようになるとします。
| PRIMARY KEY | 
|---|
| <begin> | 
| Users() | 
| Threads() | 
| Users(2) | 
| Users(3) | 
| Threads(3) | 
| Threads(3,"a") | 
| Messages(3,"a",1) | 
| Messages(3,"a",2) | 
| Threads(3, "aa") | 
| Users(9) | 
| Users(10) | 
| Threads(10) | 
| UsersByFirstName("abc") | 
| UsersByFirstName("abcd") | 
| <end> | 
スプリットの例
以下は、スプリットがどのようなものかを示す例です。
SPLIT_START と SPLIT_LIMIT は、テーブルまたはインデックスの行を表します。また、<begin> と <end> でデータベースのキースペースの境界を表す場合もあります。SPLIT_START と SPLIT_LIMIT には、テーブル内の完全なキーの前に位置し、切り捨てられたキーが含まれる場合があります。たとえば、Threads(10) は Users(10) でインターリーブされた Threads 行の接頭辞です。
| SPLIT_START | SPLIT_LIMIT | AFFECTED_TABLES | EXPLANATION | 
|---|---|---|---|
| Users(3) | Users(10) | UsersByFirstName、Users、Threads、Messages、MessagesIdx | スプリットは UserId=3の行から始まり、UserId = 10の行の前の行で終了します。スプリットには、Usersテーブルの行と、UserId=3~10 のすべてのインターリーブされたテーブルの行が含まれます。 | 
| Messages(3,"a",1) | Threads(3,"aa") | Threads、Messages、MessagesIdx | スプリットは、 UserId=3、ThreadId="a"、MessageId=1の行から始まり、UserId=3とThreadsId = "aa"のキーを持つ行の前の行で終了します。スプリットには、Messages(3,"a",1)とThreads(3,"aa")の間のすべてのテーブルが含まれます。split_startとsplit_limitは同じ最上位テーブル行にインターリーブされているため、スプリットにはスタートとリミットの間にインターリーブされたテーブル行が含まれます。インターリーブ テーブルがどのように配置されるかについては、schemas-overview をご覧ください。 | 
| Messages(3,"a",1) | <end> | UsersByFirstName、Users、Threads、Messages、MessagesIdx | スプリットは、messages テーブルでキーが UserId=3、ThreadId="a"、MessageId=1の行から開始します。スプリットは、split_startから<end>(データベースのキースペースの終了)までのすべての行をホストします。split_startの後のテーブルのすべての行(Users(4)など)がスプリットに含まれます。 | 
| <begin> | Users(9) | UsersByFirstName、Users、Threads、Messages、MessagesIdx | スプリットは、 <begin>(データベースのキースペースの先頭)から始まり、UserId=9を含むUsers行の前の行で終了します。したがって、スプリットには、Usersの前のすべてのテーブル行、UserId=9の前のUsersテーブルのすべての行、そのインターリーブ テーブルの行が含まれます。 | 
| Messages(3,"a",1) | Threads(10) | UsersByFirstName、Users、Threads、Messages、MessagesIdx | スプリットは Users(3)にインターリーブされたMessages(3,"a", 1)で始まり、Threads(10)の前の行で終わります。Threads(10)は切り捨てられたスプリットキーで、Users(10)でインターリーブされた Threads テーブルの任意のキーの接頭辞です。 | 
| Users() | <end> | UsersByFirstName、Users、Threads、Messages、MessagesIdx | スプリットは、 Usersテーブルの完全なキーの前に位置し、Users()の切り捨てられたスプリットキーから始まります。スプリットは、データベースで使用可能なキースペースの最後まで延長されます。したがって、affected_tables には、Usersテーブル、インターリーブされたテーブルとインデックス、ユーザーの後に表示される可能性があるすべてのテーブルが含まれます。 | 
| Threads(10) | UsersByFirstName("abc") | UsersByFirstName、Users、Threads、Messages、MessagesIdx | スプリットは UserId = 10のThreads行から始まり、"abc"の前のキーのインデックスUsersByFirstNameで終わります。 | 
ホット スプリットを見つけるクエリの例
次の例は、ホット スプリットの統計情報を取得するために使用できる SQL ステートメントを示しています。これらの SQL ステートメントは、クライアント ライブラリ、gcloud、または Google Cloud コンソールを使用して実行できます。
GoogleSQL
SELECT t.split_start,
       t.split_limit,
       t.cpu_usage_score,
       t.affected_tables,
FROM   SPANNER_SYS.SPLIT_STATS_TOP_MINUTE t
WHERE  t.interval_end =
  (SELECT MAX(interval_end)
  FROM    SPANNER_SYS.SPLIT_STATS_TOP_MINUTE)
ORDER BY  t.cpu_usage_score DESC;
PostgreSQL
SELECT t.split_start,
       t.split_limit,
       t.cpu_usage_score,
       t.affected_tables
FROM   SPANNER_SYS.SPLIT_STATS_TOP_MINUTE t
WHERE  t.interval_end = (
  SELECT MAX(interval_end)
  FROM   SPANNER_SYS.SPLIT_STATS_TOP_MINUTE
)
ORDER BY t.cpu_usage_score DESC;
クエリの出力は次のようになります。
| SPLIT_START | SPLIT_LIMIT | CPU_USAGE_SCORE | AFFECTED_TABLES | 
|---|---|---|---|
| Users(13) | Users(76) | 82 | Messages,Users,Threads | 
| Users(101) | Users(102) | 90 | Messages,Users,Threads | 
| Threads(10, "a") | Threads(10, "aa") | 100 | Messages,Threads | 
| Messages(631, "abc", 1) | Messages(631, "abc", 3) | 100 | Messages | 
| Threads(12, "zebra") | Users(14) | 76 | Messages,Users,Threads | 
| Users(620) | <end> | 100 | Messages,Users,Threads | 
ホット スプリット統計情報のデータ保持
Spanner は最低でも、次の期間中に各テーブルのデータを保持します。
- SPANNER_SYS.SPLIT_STATS_TOP_MINUTE: 過去 6 時間を対象とする間隔。
ホット スプリットの統計情報を使用してホットスポットのトラブルシューティングを行う
このセクションでは、ホットスポットを検出してトラブルシューティングする方法について説明します。
調査期間を選択する
Spanner データベースのレイテンシ指標を確認して、アプリケーションでレイテンシと CPU 使用率が高かった期間を見つけます。たとえば、2024 年 5 月 18 日午後 10 時 50 分頃に問題が発生したことが示される場合があります。
永続的なホットスポットを確認する
Spanner は負荷に基づいた分割によって負荷を分散するため、ホットスポットが 10 分以上続いているかどうかを調査することをおすすめします。次の例に示すように、SPANNER_SYS.SPLIT_STATS_TOP_MINUTE テーブルをクエリすることで確認できます。
GoogleSQL
SELECT Count(DISTINCT t.interval_end)
FROM   SPANNER_SYS.SPLIT_STATS_TOP_MINUTE t
WHERE  t.cpu_usage_score >= 50
  AND  t.interval_end >= "interval_end_date_time"
  AND  t.interval_end <= "interval_end_date_time";
interval_end_date_time は、2024-05-18T17:40:00Z 形式で期間の日時に置き換えます。
PostgreSQL
SELECT COUNT(DISTINCT t.interval_end)
FROM   SPLIT_STATS_TOP_MINUTE t
WHERE  t.cpu_usage_score >= 50
  AND  t.interval_end >= 'interval_end_date_time'::timestamptz
  AND  t.interval_end <= 'interval_end_date_time'::timestamptz;
interval_end_date_time は、2024-05-18T17:40:00Z 形式で期間の日時に置き換えます。
前のクエリの結果が 10 の場合、データベースでホットスポットが生じているため、さらにデバッグが必要になる可能性があります。
CPU_USAGE_SCORE レベルが最も高いスプリットを見つける
この例では、次の SQL を実行して、CPU_USAGE_SCORE レベルが最も高い行範囲を見つけます。
GoogleSQL
SELECT t.split_start,
       t.split_limit,
       t.affected_tables,
       t.cpu_usage_score
FROM   SPANNER_SYS.SPLIT_STATS_TOP_MINUTE t
WHERE  t.cpu_usage_score >= 50
  AND  t.interval_end = "interval_end_date_time";
interval_end_date_time は、2024-05-18T17:40:00Z 形式で期間の日時に置き換えます。
PostgreSQL
SELECT t.split_start,
       t.split_limit,
       t.affected_tables,
       t.cpu_usage_score
FROM   SPLIT_STATS_TOP_MINUTE t
WHERE  t.cpu_usage_score = 100
  AND  t.interval_end = 'interval_end_date_time'::timestamptz;
interval_end_date_time は、2024-05-18T17:40:00Z 形式で期間の日時に置き換えます。
上記の SQL の出力は以下のようになります。
| SPLIT_START | SPLIT_LIMIT | CPU_USAGE_SCORE | AFFECTED_TABLES | 
|---|---|---|---|
| Users(180) | <end> | 85 | Messages,Users,Threads | 
| Users(24) | Users(76) | 76 | Messages,Users,Threads | 
この結果のテーブルから、2 つのスプリットでホットスポットが発生したことがわかります。Spanner の負荷に基づいたスプリットでは、これらのスプリットでホットスポットを解決しようとすることがあります。ただし、スキーマまたはワークロードに問題のあるパターンがある場合は、解決できない可能性があります。対処が必要なスプリットがあるかどうかを確認するには、スプリットを 10 分以上追跡することをおすすめします。たとえば、次の SQL は直近 10 分間の最初のスプリットを追跡します。
GoogleSQL
SELECT t.interval_end,
       t.split_start,
       t.split_limit,
       t.cpu_usage_score
FROM   SPANNER_SYS.SPLIT_STATS_TOP_MINUTE t
WHERE  t.split_start = "users(180)"
  AND  t.split_limit = "<end>"
  AND  t.interval_end >= "interval_end_date_time"
  AND  t.interval_end <= "interval_end_date_time";
interval_end_date_time は、2024-05-18T17:40:00Z 形式で期間の日時に置き換えます。
PostgreSQL
SELECT t.interval_end,
       t.split_start,
       t.split_limit,
       t.cpu_usage_score
FROM   SPANNER_SYS.SPLIT_STATS_TOP_MINUTE t
WHERE  t.split_start = 'users(180)'
  AND  t.split_limit = ''
  AND  t.interval_end >= 'interval_end_date_time'::timestamptz
  AND  t.interval_end <= 'interval_end_date_time'::timestamptz;
interval_end_date_time は、2024-05-18T17:40:00Z 形式で期間の日時に置き換えます。
上記の SQL の出力は以下のようになります。
| INTERVAL_END | SPLIT_START | SPLIT_LIMIT | CPU_USAGE_SCORE | 
|---|---|---|---|
| 2024-05-18T17:46:00Z | Users(180) | <end> | 85 | 
| 2024-05-18T17:47:00Z | Users(180) | <end> | 85 | 
| 2024-05-18T17:48:00Z | Users(180) | <end> | 85 | 
| 2024-05-18T17:49:00Z | Users(180) | <end> | 85 | 
| 2024-05-18T17:50:00Z | Users(180) | <end> | 85 | 
スプリットは過去数分間、ホット状態になっていたようです。Spanner の負荷に基づいた分割によってホットスポットが軽減されていることを確認するために、スプリットを長時間観察することもできます。Spanner でロード バランシングをさらに進められない場合もあります。
たとえば、SPANNER_SYS.SPLIT_STATS_TOP_MINUTE テーブルにクエリを実行します。次のシナリオの例をご覧ください。
GoogleSQL
SELECT t.interval_end,
      t.split_start,
      t.split_limit,
      t.cpu_usage_score
FROM  SPANNER_SYS.SPLIT_STATS_TOP_MINUTE t
WHERE t.interval_end >= "interval_end_date_time"
      AND t.interval_end <= "interval_end_date_time";
interval_end_date_time は、2024-05-18T17:40:00Z 形式で期間の日時に置き換えます。
PostgreSQL
SELECT t.interval_end,
       t.split_start,
       t.split_limit,
       t._cpu_usage
FROM   SPANNER_SYS.SPLIT_STATS_TOP_MINUTE t
WHERE  t.interval_end >= 'interval_end_date_time'::timestamptz
  AND  t.interval_end <= 'interval_end_date_time'::timestamptz;
interval_end_date_time は、2024-05-18T17:40:00Z 形式で期間の日時に置き換えます。
単一のホット行
次の例では、Threads(10,"spanner") が 10 分以上ホット状態のままの単一行のスプリットにあることがわかります。これは、アクセスの多い行に永続的な負荷がかかっている場合に発生する可能性があります。
| INTERVAL_END | SPLIT_START | SPLIT_LIMIT | CPU_USAGE_SCORE | 
|---|---|---|---|
| 2024-05-16T20:40:00Z | Threads(10,"spanner") | Threads(10,"spanner1") | 62 | 
| 2024-05-16T20:41:00Z | Threads(10,"spanner") | Threads(10,"spanner1") | 62 | 
| 2024-05-16T20:42:00Z | Threads(10,"spanner") | Threads(10,"spanner1") | 62 | 
| 2024-05-16T20:43:00Z | Threads(10,"spanner") | Threads(10,"spanner1") | 62 | 
| 2024-05-16T20:44:00Z | Threads(10,"spanner") | Threads(10,"spanner1") | 62 | 
| 2024-05-16T20:45:00Z | Threads(10,"spanner") | Threads(10,"spanner1") | 62 | 
| 2024-05-16T20:46:00Z | Threads(10,"spanner") | Threads(10,"spanner1") | 80 | 
| 2024-05-16T20:47:00Z | Threads(10,"spanner") | Threads(10,"spanner1") | 80 | 
| 2024-05-16T20:48:00Z | Threads(10,"spanner") | Threads(10,"spanner1") | 80 | 
| 2024-05-16T20:49:00Z | Threads(10,"spanner") | Threads(10,"spanner1") | 100 | 
| 2024-05-16T20:50:00Z | Threads(10,"spanner") | Threads(10,"spanner1") | 100 | 
この単一キーはこれ以上分割できないため、Spanner はこの単一キーの負荷を分散できません。
ホットスポットの移動
次の例では、負荷が時間の経過とともに連続したスプリット間を移動し、時間間隔ごとに新しいスプリットに移動しています。
| INTERVAL_END | SPLIT_START | SPLIT_LIMIT | CPU_USAGE_SCORE | 
|---|---|---|---|
| 2024-05-16T20:40:00Z | Threads(1,"a") | Threads(1,"aa") | 100 | 
| 2024-05-16T20:41:00Z | Threads(1,"aa") | Threads(1,"ab") | 100 | 
| 2024-05-16T20:42:00Z | Threads(1,"ab") | Threads(1,"c") | 100 | 
| 2024-05-16T20:43:00Z | Threads(1,"c") | Threads(1,"ca") | 100 | 
これは、単調に増加する順にキーの読み取りまたは書き込みを行うワークロードが原因で発生する可能性があります。Spanner は、このアプリケーション動作の影響を軽減するために負荷を分散できません。
通常のロード バランシング
Spanner は、スプリットを追加するかスプリットを移動させることで、負荷を分散しようとします。次の例は、その例を示しています。
| INTERVAL_END | SPLIT_START | SPLIT_LIMIT | CPU_USAGE_SCORE | 
|---|---|---|---|
| 2024-05-16T20:40:00Z | Threads(1000,"zebra") | <end> | 82 | 
| 2024-05-16T20:41:00Z | Threads(1000,"zebra") | <end> | 90 | 
| 2024-05-16T20:42:00Z | Threads(1000,"zebra") | <end> | 100 | 
| 2024-05-16T20:43:00Z | Threads(1000,"zebra") | Threads(2000,"spanner") | 100 | 
| 2024-05-16T20:44:00Z | Threads(1200,"c") | Threads(2000) | 92 | 
| 2024-05-16T20:45:00Z | Threads(1500,"c") | Threads(1700,"zach") | 76 | 
| 2024-05-16T20:46:00Z | Threads(1700) | Threads(1700,"c") | 76 | 
| 2024-05-16T20:47:00Z | Threads(1700) | Threads(1700,"c") | 50 | 
| 2024-05-16T20:48:00Z | Threads(1700) | Threads(1700,"c") | 39 | 
ここでは、2024-05-16T17:40:00Z の大きなスプリットがさらに小さなスプリットに分割され、その結果、CPU_USAGE_SCORE の統計情報が減少しました。Spanner は、個々の行にスプリットを作成しない場合があります。スプリットは、大量の CPU_USAGE_SCORE 統計情報の原因となるワークロードをミラーリングします。
ホット スプリットが 10 分以上持続している場合は、ホットスポットを軽減するためのベスト プラクティスをご覧ください。
ホットスポットを軽減するためのベスト プラクティス
ロード バランシングでレイテンシが軽減しない場合は、ホットスポットの原因を特定します。その後、ホットスポット ワークロードを減らすか、アプリケーション スキーマとロジックを最適化してホットスポットを回避します。
原因を特定する
- ロックとトランザクションの分析情報を使用して、行範囲のスタートキーがホットスプリット内にある、ロック待機時間の長いトランザクションを探します。 
- クエリの分析情報を使用して、ホット スプリットを含むテーブルから読み取られ、最近レイテンシが増加しているクエリ、またはレイテンシと CPU の比率が高いクエリを探します。 
- 最も古いアクティブ クエリを使用して、ホット スプリットを含むテーブルから読み取られ、予想よりもレイテンシが高いクエリを探します。 
次のような特別な状況には注意が必要です。
- 有効期間(TTL)が最近有効にされたかどうかを確認します。古いデータからのスプリットが多い場合、TTL により一括削除中に CPU_USAGE_SCOREレベルが上昇する可能性があります。この場合、最初の削除が完了すると、問題は自動的に解決します。
ワークロードを最適化する
- SQL のベスト プラクティスに従います。古い読み取り、読み取りを先に行わない書き込み、インデックスの追加を検討してください。
- スキーマのベスト プラクティスに従います。ロード バランシングを処理し、ホットスポットを回避するようにスキーマが設計されていることを確認します。
次のステップ
- スキーマ設計のベスト プラクティスについて確認する。
- Key Visualizer について確認する。
- スキーマ設計の例を見る。
- スプリット分析情報ダッシュボードを使用してホットスポットを検出する方法を確認する。