Azure SQL Database でのクエリのパフォーマンスを手動でチューニングするManual tune query performance in Azure SQL Database

SQL Database で発生しているパフォーマンスの問題が明らかになったら、この記事を読むと次のことに役立ちます。Once you have identified a performance issue that you are facing with SQL Database, this article is designed to help you:

  • アプリケーションを調整し、パフォーマンスを向上させるベスト プラクティスを適用します。Tune your application and apply some best practices that can improve performance.
  • データをより効率的に処理するようにインデックスとクエリを変更して、データベースをチューニングします。Tune the database by changing indexes and queries to more efficiently work with data.

この記事では、Azure SQL Database のデータベース アドバイザーの推奨事項および Azure SQL Database の自動チューニングの推奨事項に従った作業を既に行っているものとします。This article assumes that you have already worked through the Azure SQL Database database advisor recommendations and the Azure SQL Database auto-tuning recommendations. また、監視とチューニングの概要に関する記事およびパフォーマンスの問題のトラブルシューティングに関するその関連記事を読んであるものとします。It also assumes that you have reviewed An overview of monitoring and tuning and its related articles related to troubleshooting performance issues. さらに、この記事では、CPU リソースに、コンピューティング サイズまたはサービス レベルを上げてデータベースに対するリソースを増やすことで解決できる実行関連のパフォーマンスの問題がないことを前提としています。Additionally, this article assumes that you do not have a CPU resources, running-related performance issue that can be resolved by increasing the compute size or service tier to provide more resources to your database.

アプリケーションの調整Tune your application

従来のオンプレミス SQL Server では多くの場合、初回の容量計画のプロセスは、運用環境でアプリケーションを実行するプロセスから分離されます。In traditional on-premises SQL Server, the process of initial capacity planning often is separated from the process of running an application in production. 最初にハードウェアと製品ライセンスが購入され、パフォーマンス調整は後で行われます。Hardware and product licenses are purchased first, and performance tuning is done afterward. Azure SQL Database を使用する場合、アプリケーションの実行と調整のプロセスを組み合わせることをお勧めします。When you use Azure SQL Database, it's a good idea to interweave the process of running an application and tuning it. オンデマンド容量の支払いモデルでは、現在必要とされる最小のリソースを使用するようにアプリケーションを調整できます。(不正確なことが多い) アプリケーションの将来的な成長計画の推測に基づいて、ハードウェアに過剰プロビジョニングを行うことはしません。With the model of paying for capacity on demand, you can tune your application to use the minimum resources needed now, instead of over-provisioning on hardware based on guesses of future growth plans for an application, which often are incorrect. アプリケーションを調整しないでハードウェア リソースを過剰にプロビジョニングすることを選ぶユーザーもいます。Some customers might choose not to tune an application, and instead choose to over-provision hardware resources. この方法は、利用が集中する期間に重要なアプリケーションの変更を望まない場合に適していることがあります。This approach might be a good idea if you don't want to change a key application during a busy period. しかし、アプリケーションを調整することで、リソース要件を最小限に抑え、Azure SQL Database のサービス レベルを使用する際に毎月の請求額を抑えることができます。But, tuning an application can minimize resource requirements and lower monthly bills when you use the service tiers in Azure SQL Database.

アプリケーションの特性Application characteristics

Azure SQL Database のサービス レベルは、アプリケーションのパフォーマンスの安定性と予測可能性を高めるように設計されています。一方で、いくつかのベスト プラクティスを実践することで、コンピューティング サイズ内でリソースを最大限に活用するようアプリケーションを調整できます。Although Azure SQL Database service tiers are designed to improve performance stability and predictability for an application, some best practices can help you tune your application to better take advantage of the resources at a compute size. 多くのアプリケーションは、上位のコンピューティング サイズまたはサービス レベルに切り替えることでパフォーマンスが大幅に向上します。とはいえ、アプリケーションによっては、上位のサービス レベルの利点を活かすためにさらに調整が必要になります。Although many applications have significant performance gains simply by switching to a higher compute size or service tier, some applications need additional tuning to benefit from a higher level of service. 次のような特性を備えたアプリケーションでは、パフォーマンスを向上させるためにアプリケーションに調整を加えることを検討してください。For increased performance, consider additional application tuning for applications that have these characteristics:

  • "煩雑な" 動作が原因でパフォーマンスの低いアプリケーションApplications that have slow performance because of "chatty" behavior

    煩雑なアプリケーションでは、ネットワークの待機時間が重要なデータ アクセス操作が過度に発生します。Chatty applications make excessive data access operations that are sensitive to network latency. この種のアプリケーションでは、SQL データベースに対するデータ アクセス操作の数を減らすよう変更を施す必要があります。You might need to modify these kinds of applications to reduce the number of data access operations to the SQL database. たとえば、アドホック クエリを一括処理したり、ストアド プロシージャにクエリを移動したりするなどの手法を使って、アプリケーションのパフォーマンスを向上させることができます。For example, you might improve application performance by using techniques like batching ad hoc queries or moving the queries to stored procedures. 詳細については、「 バッチ クエリ」を参照してください。For more information, see Batch queries.

  • 単一のマシンではサポートし切れないほどワークロードが集中するデータベースDatabases with an intensive workload that can't be supported by an entire single machine

    最高の Premium コンピューティング サイズのリソースを超えるデータベースでは、ワークロードのスケールアウトを活用できる場合があります。Databases that exceed the resources of the highest Premium compute size might benefit from scaling out the workload. 詳細については、「データベース間のシャーディング」と「機能的パーティション分割」を参照してください。For more information, see Cross-database sharding and Functional partitioning.

  • 最適でないクエリを含むアプリケーションApplications that have sub-optimal queries

    クエリが十分に調整されていない (特にデータ アクセス層の) アプリケーションの場合、上位のコンピューティング サイズの利点を活かせないことがあります。Applications, especially those in the data access layer, that have poorly tuned queries might not benefit from a higher compute size. たとえば、WHERE 句がない、インデックスが足りない、統計が古いクエリです。This includes queries that lack a WHERE clause, have missing indexes, or have outdated statistics. これらのアプリケーションの場合、クエリ パフォーマンスの標準的な調整方法で効果が得られます。These applications benefit from standard query performance-tuning techniques. 詳細については、「インデックスの不足」と「クエリの調整とヒント」を参照してください。For more information, see Missing indexes and Query tuning and hinting.

  • データ アクセス設計が最適ではないアプリケーションApplications that have sub-optimal data access design

    デッドロックなど、データ アクセスの同時性問題が内在するアプリケーションの場合、上位のコンピューティング サイズの利点を活かせないことがあります。Applications that have inherent data access concurrency issues, for example deadlocking, might not benefit from a higher compute size. Azure キャッシュ サービスや他のキャッシング技術を利用し、クライアント側でデータをキャッシュすることで、Azure SQL Database に対するラウンド トリップを減らすことを検討してください。Consider reducing round trips against the Azure SQL Database by caching data on the client side with the Azure Caching service or another caching technology. 詳しくは、「 アプリケーション層のキャッシュ」を参照してください。See Application tier caching.

データベースの調整Tune your database

このセクションでは、Azure SQL Database を調整するいくつかの手法について説明します。これらの手法を使用すると、アプリケーションから最良のパフォーマンスを引き出し、可能な限り下位のコンピューティング サイズでアプリケーションを実行することができます。In this section, we look at some techniques that you can use to tune Azure SQL Database to gain the best performance for your application and run it at the lowest possible compute size. これらの手法の一部は従来の SQL Server 調整のベスト プラクティスと同じですが、その他のものは Azure SQL Database に固有です。Some of these techniques match traditional SQL Server tuning best practices, but others are specific to Azure SQL Database. 場合によっては、データベースで使用されるリソースを調べ、さらに調整すべき領域を見つけることができるほか、従来の SQL Server 手法を拡大し、Azure SQL Database に応用することができます。In some cases, you can examine the consumed resources for a database to find areas to further tune and extend traditional SQL Server techniques to work in Azure SQL Database.

不足しているインデックスの識別と追加Identifying and adding missing indexes

OLTP データベースのパフォーマンスの一般的問題は物理的なデータベース設計に関連します。A common problem in OLTP database performance relates to the physical database design. 多くの場合、データベース スキーマは (負荷またはデータ量の) 規模の面で試験することなく設計され、出荷されます。Often, database schemas are designed and shipped without testing at scale (either in load or in data volume). 残念ながら、クエリ プランのパフォーマンスは、規模が小さい場合には許容されることがあるものの、実稼働レベルのデータ量では大幅に低下する可能性があります。Unfortunately, the performance of a query plan might be acceptable on a small scale but degrade substantially under production-level data volumes. この問題の最も一般的な原因は、適切なインデックスがなく、クエリのフィルターまたはその他の制約を満たせないことにあります。The most common source of this issue is the lack of appropriate indexes to satisfy filters or other restrictions in a query. 多くの場合、インデックスがないと、インデックス シークで足りるときにテーブル スキャンが行われます。Often, missing indexes manifests as a table scan when an index seek could suffice.

次の例では、シークで足りるときに、選択したクエリ プランでスキャンが使用されます。In this example, the selected query plan uses a scan when a seek would suffice:

DROP TABLE dbo.missingindex;
CREATE TABLE dbo.missingindex (col1 INT IDENTITY PRIMARY KEY, col2 INT);
DECLARE @a int = 0;
SET NOCOUNT ON;
BEGIN TRANSACTION
    WHILE @a < 20000
    BEGIN
        INSERT INTO dbo.missingindex(col2) VALUES (@a);
        SET @a += 1;
    END
    COMMIT TRANSACTION;
    GO
SELECT m1.col1
    FROM dbo.missingindex m1 INNER JOIN dbo.missingindex m2 ON(m1.col1=m2.col1)
    WHERE m1.col2 = 4;

A query plan with missing indexes

Azure SQL Database は、インデックス不足の一般的な状態を発見して修正するのに役立ちます。Azure SQL Database can help you find and fix common missing index conditions. Azure SQL Database に組み込まれている DMV には、クエリ コンパイルが表示されます。クエリを実行するために見積もられたコストをインデックスで大幅に削減できる場合があります。DMVs that are built into Azure SQL Database look at query compilations in which an index would significantly reduce the estimated cost to run a query. クエリの実行中、SQL Database によって、各クエリ プランが実行される頻度と、実行クエリ プランとそのインデックスが存在した想定クエリ プランの間で見積もられるギャップが追跡されます。During query execution, SQL Database tracks how often each query plan is executed, and tracks the estimated gap between the executing query plan and the imagined one where that index existed. これらの DMV を使用し、データベースとその実際のワークロードに関してワークロード コストを全体的に改善できる物理データベース設計の変更をすばやく推測できます。You can use these DMVs to quickly guess which changes to your physical database design might improve overall workload cost for a database and its real workload.

次のクエリは、潜在的なインデックス不足の評価に使用できます。You can use this query to evaluate potential missing indexes:

SELECT
   CONVERT (varchar, getdate(), 126) AS runtime
   , mig.index_group_handle
   , mid.index_handle
   , CONVERT (decimal (28,1), migs.avg_total_user_cost * migs.avg_user_impact *
        (migs.user_seeks + migs.user_scans)) AS improvement_measure
   , 'CREATE INDEX missing_index_' + CONVERT (varchar, mig.index_group_handle) + '_' +
        CONVERT (varchar, mid.index_handle) + ' ON ' + mid.statement + '
        (' + ISNULL (mid.equality_columns,'')
        + CASE WHEN mid.equality_columns IS NOT NULL
        AND mid.inequality_columns IS NOT NULL
        THEN ',' ELSE '' END + ISNULL (mid.inequality_columns, '') + ')'
        + ISNULL (' INCLUDE (' + mid.included_columns + ')', '') AS create_index_statement
   , migs.*
   , mid.database_id
   , mid.[object_id]
FROM sys.dm_db_missing_index_groups AS mig
   INNER JOIN sys.dm_db_missing_index_group_stats AS migs
      ON migs.group_handle = mig.index_group_handle
   INNER JOIN sys.dm_db_missing_index_details AS mid
      ON mig.index_handle = mid.index_handle
 ORDER BY migs.avg_total_user_cost * migs.avg_user_impact * (migs.user_seeks + migs.user_scans) DESC

この例では、クエリの結果として次が推奨されました。In this example, the query resulted in this suggestion:

CREATE INDEX missing_index_5006_5005 ON [dbo].[missingindex] ([col2])  

作成後、同じ SELECT ステートメントを実行すると、異なるプランが選択されます。スキャンではなくシークが使用され、プランがより効率的に実行されます。After it's created, that same SELECT statement picks a different plan, which uses a seek instead of a scan, and then executes the plan more efficiently:

A query plan with corrected indexes

重要なことは、共有される汎用システムの IO 容量は専用サーバー コンピューターの IO 容量より限られているということです。The key insight is that the IO capacity of a shared, commodity system is more limited than that of a dedicated server machine. 不必要な IO を最小限に抑え、Azure SQL Database サービス レベルの各コンピューティング サイズの DTU 内でシステムを最大限に活用することが重要です。There's a premium on minimizing unnecessary IO to take maximum advantage of the system in the DTU of each compute size of the Azure SQL Database service tiers. 適切な物理データベース設計を選択すると、個々のクエリの待機時間のほか、スケール ユニットごとに処理される同時要求のスループットを大幅に改善し、クエリを満たすために必要なコストを最小限に抑えることができます。Appropriate physical database design choices can significantly improve the latency for individual queries, improve the throughput of concurrent requests handled per scale unit, and minimize the costs required to satisfy the query. インデックス不足の DMV に関する詳細については、「sys.dm_db_missing_index_details」を参照してください。For more information about the missing index DMVs, see sys.dm_db_missing_index_details.

クエリの調整とヒントQuery tuning and hinting

Azure SQL Database のクエリ オプティマイザーは、従来の SQL Server クエリ オプティマイザーと似ています。The query optimizer in Azure SQL Database is similar to the traditional SQL Server query optimizer. クエリを調整し、クエリ オプティマイザーの推論モデル制約を理解するためのベスト プラクティスのほとんどは、Azure SQL Database にも活かすことができます。Most of the best practices for tuning queries and understanding the reasoning model limitations for the query optimizer also apply to Azure SQL Database. Azure SQL Database のクエリを調整すると、総リソース要求を減らせる場合があります。If you tune queries in Azure SQL Database, you might get the additional benefit of reducing aggregate resource demands. 下位のコンピューティング サイズで実行できるため、クエリが調整されていない場合に比べて少ないコストでアプリケーションを実行できます。Your application might be able to run at a lower cost than an un-tuned equivalent because it can run at a lower compute size.

SQL Server でよく見られ Azure SQL Database にも適用される例は、クエリ オプティマイザーによるパラメーターの "スニッフィング" です。An example that is common in SQL Server and which also applies to Azure SQL Database is how the query optimizer "sniffs" parameters. コンパイル中、クエリ オプティマイザーによってパラメーターの現在の値が評価され、より最適なクエリ プランを生成できるかどうかが判断されます。During compilation, the query optimizer evaluates the current value of a parameter to determine whether it can generate a more optimal query plan. この戦略を使用すると多くの場合、既知のパラメーター値を使用せずにコンパイルされたプランよりもはるかに速いクエリ プランが生成されます。ただし現時点では、SQL Server と Azure SQL Database の両方で動作が不完全です。Although this strategy often can lead to a query plan that is significantly faster than a plan compiled without known parameter values, currently it works imperfectly both in SQL Server and in Azure SQL Database. パラメーターがスニッフィングされなかったり、パラメーターがスニッフィングされたものの、生成されたプランがワークロードのすべてのパラメーター値に関して最適でなかったりする場合があります。Sometimes the parameter is not sniffed, and sometimes the parameter is sniffed but the generated plan is sub-optimal for the full set of parameter values in a workload. 意図をより慎重に指定し、パラメーター スニッフィングの既定の動作をオーバーライドできるように、Microsoft はクエリ ヒント (ディレクティブ) を追加しています。Microsoft includes query hints (directives) so that you can specify intent more deliberately and override the default behavior of parameter sniffing. 多くの場合、ヒントを使用すると、SQL Server または Azure SQL Database の既定の動作で特定のユーザーのワークロードに完全に対応できない問題を修正できます。Often, if you use hints, you can fix cases in which the default SQL Server or Azure SQL Database behavior is imperfect for a specific customer workload.

次の例は、パフォーマンスとリソースの両方の要件について最適でないプランがクエリ プロセッサによって生成されるようすを示しています。The next example demonstrates how the query processor can generate a plan that is sub-optimal both for performance and resource requirements. この例から、クエリ ヒントを使用すると、SQL データベースのクエリの実行時間とリソース要件を抑えることができることもわかります。This example also shows that if you use a query hint, you can reduce query run time and resource requirements for your SQL database:

DROP TABLE psptest1;
CREATE TABLE psptest1(col1 int primary key identity, col2 int, col3 binary(200));
DECLARE @a int = 0;
SET NOCOUNT ON;
BEGIN TRANSACTION
   WHILE @a < 20000
   BEGIN
     INSERT INTO psptest1(col2) values (1);
     INSERT INTO psptest1(col2) values (@a);
     SET @a += 1;
   END
   COMMIT TRANSACTION
   CREATE INDEX i1 on psptest1(col2);
GO

CREATE PROCEDURE psp1 (@param1 int)
   AS
   BEGIN
      INSERT INTO t1 SELECT * FROM psptest1
      WHERE col2 = @param1
      ORDER BY col2;
    END
    GO

CREATE PROCEDURE psp2 (@param2 int)
   AS
   BEGIN
      INSERT INTO t1 SELECT * FROM psptest1 WHERE col2 = @param2
      ORDER BY col2
      OPTION (OPTIMIZE FOR (@param2 UNKNOWN))
   END
   GO

CREATE TABLE t1 (col1 int primary key, col2 int, col3 binary(200));
GO

このセットアップ コードによって、傾斜データ分布が含まれたテーブルが作成されます。The setup code creates a table that has skewed data distribution. 最適なクエリ プランは、選択されたパラメーターによって異なります。The optimal query plan differs based on which parameter is selected. 残念ながらプラン キャッシング動作では、常に最も一般的なパラメーター値に基づいてクエリが再コンパイルされるとは限りません。Unfortunately, the plan caching behavior doesn't always recompile the query based on the most common parameter value. そのため、平均すると別のプランの方がプランとしてより良い選択になる場合でも、最適でないプランがキャッシュされ、多くの値に使用される可能性があります。So, it's possible for a sub-optimal plan to be cached and used for many values, even when a different plan might be a better plan choice on average. 次に、(一方に特殊なクエリ ヒントが含まれていることを除いて) 同一の 2 つのストアド プロシージャがクエリ プランによって作成されます。Then the query plan creates two stored procedures that are identical, except that one has a special query hint.

-- Prime Procedure Cache with scan plan
EXEC psp1 @param1=1;
TRUNCATE TABLE t1;

-- Iterate multiple times to show the performance difference
DECLARE @i int = 0;
WHILE @i < 1000
   BEGIN
      EXEC psp1 @param1=2;
      TRUNCATE TABLE t1;
      SET @i += 1;
    END

例のパート 2 を開始する前に少なくとも 10 分待つことをお勧めします。これにより、生成されるテレメトリ データの結果の差異がはっきりします。We recommend that you wait at least 10 minutes before you begin part 2 of the example, so that the results are distinct in the resulting telemetry data.

EXEC psp2 @param2=1;
TRUNCATE TABLE t1;

DECLARE @i int = 0;
    WHILE @i < 1000
    BEGIN
        EXEC psp2 @param2=2;
        TRUNCATE TABLE t1;
        SET @i += 1;
    END

この例の各パートでは、(テスト データ セットとして使用するのに十分な負荷を生成するために) パラメーター化された挿入ステートメントが 1,000 回試行されます。Each part of this example attempts to run a parameterized insert statement 1,000 times (to generate a sufficient load to use as a test data set). ストアド プロシージャを実行するとき、クエリ プロセッサは、その最初のコンパイル中にプロシージャに渡されるパラメーター値を調べます (パラメーターの "スニッフィング")。When it executes stored procedures, the query processor examines the parameter value that is passed to the procedure during its first compilation (parameter "sniffing"). 結果として生成されたプランがプロセッサによってキャッシュされ、パラメーター値が異なる場合でも、後の呼び出しで使用されます。The processor caches the resulting plan and uses it for later invocations, even if the parameter value is different. 最適なプランが使用されないことがあります。The optimal plan might not be used in all cases. クエリが最初にコンパイルされたときのケースではなく、平均的なケースに対して最適なプランを選択するように、オプティマイザーを調整する必要がある場合があります。Sometimes you need to guide the optimizer to pick a plan that is better for the average case rather than the specific case from when the query was first compiled. この例では、最初のプランは、パラメーターに一致する各値を見つけるためにすべての行を読み取る "スキャン" プランを生成します。In this example, the initial plan generates a "scan" plan that reads all rows to find each value that matches the parameter:

Query tuning by using a scan plan

値 1 を使用してプロシージャを実行したため、結果として生成されたプランは値 1 に対して最適ですが、テーブルにある他のすべての値に対しては最適ではありません。Because we executed the procedure by using the value 1, the resulting plan was optimal for the value 1 but was sub-optimal for all other values in the table. 各プランを無作為に選択した場合、結果は望んだものと異なることが予想されます。これは、プランの実行が遅く、より多くのリソースが使用されるためです。The result likely isn't what you would want if you were to pick each plan randomly, because the plan performs more slowly and uses more resources.

SET STATISTICS IOON に設定してテストを実行すると、この例の論理スキャン作業がバックグラウンドで行われます。If you run the test with SET STATISTICS IO set to ON, the logical scan work in this example is done behind the scenes. このプランによって 1,148 件の読み取りが行われたことがわかります (平均的なケースで返される行がたった 1 つの場合、非効率的です)。You can see that there are 1,148 reads done by the plan (which is inefficient, if the average case is to return just one row):

Query tuning by using a logical scan

例の 2 つ目の部分では、クエリ ヒントを利用し、コンパイル プロセス中に特定の値を使用するようにオプティマイザーに伝えます。The second part of the example uses a query hint to tell the optimizer to use a specific value during the compilation process. この場合、パラメーターとして渡される値を無視し、UNKNOWN を想定するようにクエリ プロセッサに強制します。In this case, it forces the query processor to ignore the value that is passed as the parameter, and instead to assume UNKNOWN. これはテーブル内での頻度が平均的な値を示します (傾斜を無視)。This refers to a value that has the average frequency in the table (ignoring skew). 結果として生成されるプランはシークベースのプランです。このプランはこの例のパート 1 のプランより全体的に高速であり、このプランで使用されるリソースもパート 1 のプランより全体的に少なくなっています。The resulting plan is a seek-based plan that is faster and uses fewer resources, on average, than the plan in part 1 of this example:

Query tuning by using a query hint

sys.resource_stats テーブルで影響を確認できます (テストを実行してからデータがテーブルに入力されるまでの間に遅延があります)。You can see the effect in the sys.resource_stats table (there is a delay from the time that you execute the test and when the data populates the table). この例では、パート 1 は 22:25:00 の時間枠で実行され、パート 2 は 22:35:00 の時間枠で実行されています。For this example, part 1 executed during the 22:25:00 time window, and part 2 executed at 22:35:00. 遅い方の時間枠と比べ、早い方の時間枠でその時間枠のリソースがより多く使用されます (プランの効率性改善が理由)。The earlier time window used more resources in that time window than the later one (because of plan efficiency improvements).

SELECT TOP 1000 *
FROM sys.resource_stats
WHERE database_name = 'resource1'
ORDER BY start_time DESC

Query tuning example results

注意

この例では規模を意図的に小さくしてありますが、最適でないパラメーターの影響は特に大規模なデータベースで顕著になります。Although the volume in this example is intentionally small, the effect of sub-optimal parameters can be substantial, especially on larger databases. 極端なケースでは、速い場合は数秒単位、遅い場合は数時間単位の差異になります。The difference, in extreme cases, can be between seconds for fast cases and hours for slow cases.

sys.resource_stats を調べると、あるテストで使用されるリソースが別のテストより多いか少ないか判断できます。You can examine sys.resource_stats to determine whether the resource for a test uses more or fewer resources than another test. データを比較するとき、sys.resource_stats ビューで同じ 5 分の枠に入らないようにテストのタイミングを離します。When you compare data, separate the timing of tests so that they are not in the same 5-minute window in the sys.resource_stats view. この演習の目標は、使用されるリソースの総量を最小限に抑えることであり、ピーク リソースを最小限に抑えることではありません。The goal of the exercise is to minimize the total amount of resources used, and not to minimize the peak resources. 一般的に、待ち時間のコードの一部を最適化すると、リソースの消費量も減ります。Generally, optimizing a piece of code for latency also reduces resource consumption. アプリケーションに施す変更が必要なものであることと、アプリケーションでクエリ ヒントを使用している他のユーザーのカスタマー エクスペリエンスに対し変更による悪影響がないことを確認してください。Make sure that the changes you make to an application are necessary, and that the changes don't negatively affect the customer experience for someone who might be using query hints in the application.

ワークロードに一連の反復的なクエリが含まれる場合は、データベースをホストするために必要な最小リソース サイズ単位を把握できるため、たいてい、プラン選択肢の最適性を理解して検証することは合理的です。If a workload has a set of repeating queries, often it makes sense to capture and validate the optimality of your plan choices because it drives the minimum resource size unit required to host the database. 検証した後、プランのパフォーマンスが低くなっていないことを確認するために、ときどきプランを調べ直してください。After you validate it, occasionally reexamine the plans to help you make sure that they have not degraded. 詳細については、「 クエリ ヒント (Transact-SQL)」をご覧ください。You can learn more about query hints (Transact-SQL).

データベース間のシャーディングCross-database sharding

Azure SQL Database は汎用ハードウェアで実行されるため、従来のオンプレミス SQL Server インストールと比べ、1 つのデータベースに対する容量制限が低くなります。Because Azure SQL Database runs on commodity hardware, the capacity limits for an individual database are lower than for a traditional on-premises SQL Server installation. データベース操作が Azure SQL Database の 1 つのデータベースの制限内に収まらないときにシャーディング手法を使用して、複数のデータベースに操作を分散しているユーザーもいます。Some customers use sharding techniques to spread database operations over multiple databases when the operations don't fit inside the limits of an individual database in Azure SQL Database. Azure SQL Database でシャーディング手法を利用するほとんどのユーザーは、1 つのディメンションのデータを複数のデータベースで分割します。Most customers who use sharding techniques in Azure SQL Database split their data on a single dimension across multiple databases. この手法では、OLTP アプリケーションは多くの場合、スキーマ内の 1 行のみ、またはほんの数行から成るグループに適用されるトランザクションを実行することを理解しておく必要があります。For this approach, you need to understand that OLTP applications often perform transactions that apply to only one row or to a small group of rows in the schema.

注意

SQL Database にシャーディングを支援するライブラリが追加されました。SQL Database now provides a library to assist with sharding. 詳細については、「 エラスティック データベース クライアント ライブラリの概要」をご覧ください。For more information, see Elastic Database client library overview.

たとえば、(SQL Server 付属の従来のサンプル Northwind データベースのように) あるデータベースに顧客名、注文、注文明細が含まれている場合、関連する注文と注文明細の情報を使って顧客をグループ化することで、このデータを複数のデータベースに分割できます。For example, if a database has customer name, order, and order details (like the traditional example Northwind database that ships with SQL Server), you could split this data into multiple databases by grouping a customer with the related order and order detail information. 顧客のデータは 1 つのデータベース内にとどめておくことができます。You can guarantee that the customer's data stays in an individual database. アプリケーションはデータベース間で顧客を分割し、効果的に負荷を分散します。The application would split different customers across databases, effectively spreading the load across multiple databases. シャーディングを使用すると、顧客がデータベース サイズの上限を回避できるだけでなく、個々のデータベースがその DTU に収まる限り、各コンピューティング サイズの制限を大幅に超えるワークロードを Azure SQL Database で処理できます。With sharding, customers not only can avoid the maximum database size limit, but Azure SQL Database also can process workloads that are significantly larger than the limits of the different compute sizes, as long as each individual database fits into its DTU.

データベース シャーディングではソリューションの総リソース容量を減らすことはできませんが、複数のデータベースにまたがる非常に大規模なソリューションに対応する際に非常に効果的です。Although database sharding doesn't reduce the aggregate resource capacity for a solution, it's highly effective at supporting very large solutions that are spread over multiple databases. 各データベースを異なるコンピューティング サイズで実行し、リソース要件の高い、非常に大規模で "効果的な" データベースに対応できます。Each database can run at a different compute size to support very large, "effective" databases with high resource requirements.

機能的パーティション分割Functional partitioning

SQL Server ユーザーは多くの場合、1 つのデータベースのさまざまな機能を組み合わせます。SQL Server users often combine many functions in an individual database. たとえば、店舗の在庫を管理するロジックがアプリケーションに含まれている場合、そのデータベースには、在庫に関連付けられているロジック、購買発注の追跡、ストアド プロシージャ、月末報告を管理するインデックス付きビュー/具体化されたビューが含まれていることがあります。For example, if an application has logic to manage inventory for a store, that database might have logic associated with inventory, tracking purchase orders, stored procedures, and indexed or materialized views that manage end-of-month reporting. この手法では、バックアップなどの操作に関するデータベースの管理が容易になりますが、アプリケーションの機能全体でピーク負荷を処理できるようにハードウェアのサイズを調整する必要もあります。This technique makes it easier to administer the database for operations like backup, but it also requires you to size the hardware to handle the peak load across all functions of an application.

Azure SQL Database 内でスケールアウト アーキテクチャを使用する場合、アプリケーションの異なる機能を異なるデータベースに分割することをお勧めします。If you use a scale-out architecture in Azure SQL Database, it's a good idea to split different functions of an application into different databases. この手法を使用すると、各アプリケーションは独立してスケールされます。By using this technique, each application scales independently. 管理者は、アプリケーションがビジー状態になった (データベースの負荷が増えた) ときに、アプリケーションの機能ごとにコンピューティング サイズを個別に選択できます。As an application becomes busier (and the load on the database increases), the administrator can choose independent compute sizes for each function in the application. 制限はありますが、このアーキテクチャを使用して、1 台の汎用コンピューターで処理できる範囲を超えてアプリケーションの規模を大きくできます。これは、複数のコンピューター間で負荷が分散されるためです。At the limit, with this architecture, an application can be larger than a single commodity machine can handle because the load is spread across multiple machines.

バッチ クエリBatch queries

大量のアドホック クエリを頻繁に実行してデータにアクセスするアプリケーションの場合、アプリケーション層と Azure SQL Database 層の間で行われるネットワーク通信の応答に、相当な時間が費やされます。For applications that access data by using high-volume, frequent, ad hoc querying, a substantial amount of response time is spent on network communication between the application tier and the Azure SQL Database tier. アプリケーションと Azure SQL Database が両方同じデータ センターに存在する場合でも、データ アクセス操作の数が多ければ、この 2 つの間のネットワーク待機時間は長くなる可能性があります。Even when both the application and Azure SQL Database are in the same data center, the network latency between the two might be magnified by a large number of data access operations. データ アクセス操作のネットワーク ラウンド トリップを減らすために、アドホック クエリを一括処理すること、またはストアド プロシージャとしてそれらをコンパイルすることを検討してください。To reduce the network round trips for the data access operations, consider using the option to either batch the ad hoc queries, or to compile them as stored procedures. アドホック クエリを一括処理すると、複数のクエリを 1 つの大きなバッチとして 1 回のトリップで Azure SQL Database に送信できます。If you batch the ad hoc queries, you can send multiple queries as one large batch in a single trip to Azure SQL Database. アドホック クエリをストアド プロシージャにコンパイルすると、それらを一括処理した場合と同じ結果が得られます。If you compile ad hoc queries in a stored procedure, you could achieve the same result as if you batch them. ストアド プロシージャを使用すると、クエリ プランが Azure SQL Database にキャッシュされる機会が増えるという利点もあるため、ストアド プロシージャを再度使用できます。Using a stored procedure also gives you the benefit of increasing the chances of caching the query plans in Azure SQL Database so you can use the stored procedure again.

一部のアプリケーションでは、書き込みが集中します。Some applications are write-intensive. 場合によっては、書き込みを一括処理する方法を検討することで、データベースの IO 総負荷を減らすことができます。Sometimes you can reduce the total IO load on a database by considering how to batch writes together. これは多くの場合、ストアド プロシージャとアドホック バッチ内で自動コミット トランザクションではなく明示的なトランザクションを使用するのと同じくらい単純です。Often, this is as simple as using explicit transactions instead of auto-commit transactions in stored procedures and ad hoc batches. 使用できるさまざまな手法の評価については、 Azure での SQL Database アプリケーションのバッチ処理手法に関する記事を参照してください。For an evaluation of different techniques you can use, see Batching techniques for SQL Database applications in Azure. 独自のワークロードで実験を行って、一括処理に適したモデルを見つけてください。Experiment with your own workload to find the right model for batching. モデルによってはトランザクションの整合性の保証がわずかに異なる場合があることを理解しておいてください。Be sure to understand that a model might have slightly different transactional consistency guarantees. リソース使用を最小限に抑える適切なワークロードを見つけるには、整合性とパフォーマンスの適度なバランスを見つける必要があります。Finding the right workload that minimizes resource use requires finding the right combination of consistency and performance trade-offs.

アプリケーション層のキャッシュApplication-tier caching

一部のデータベース アプリケーションでは、ワークロードの大半が読み取りになります。Some database applications have read-heavy workloads. キャッシュ層を利用すれば、データベースの負荷を減らすことができます。また、Azure SQL Database を使用してデータベースをサポートするために必要なコンピューティング サイズを下げられる可能性があります。Caching layers might reduce the load on the database and might potentially reduce the compute size required to support a database by using Azure SQL Database. Azure Cache for Redis を利用すると、読み取りが多いワークロードがある場合に、データを 1 回 (または、構成方法に応じてアプリケーション層コンピューターごとに 1 回) 読み込んでから、SQL データベースの外部にそのデータを格納することができます。With Azure Cache for Redis, if you have a read-heavy workload, you can read the data once (or perhaps once per application-tier machine, depending on how it is configured), and then store that data outside your SQL database. この方法は、データベースの負荷 (CPU と読み取り IO) を減らすことができるものの、トランザクションの整合性に影響があります。データがキャッシュから読み込まれると、データベースのデータとの同期が失われることがあるためです。This is a way to reduce database load (CPU and read IO), but there is an effect on transactional consistency because the data being read from the cache might be out of sync with the data in the database. 多くのアプリケーションではある程度の不整合が許容されますが、すべてのワークロードで許容されるとは限りません。Although in many applications some level of inconsistency is acceptable, that's not true for all workloads. アプリケーション層のキャッシュ手法を実装する前に、あらゆるアプリケーション要件を完全に理解しておく必要があります。You should fully understand any application requirements before you implement an application-tier caching strategy.

次の手順Next steps