Azure SQL Database でデータベース間のクエリが可能に

このポストは、10 月 15 日に投稿された Cross-Database Queries in Azure SQL Database の翻訳です。

今回、Azure SQL Database の Elastic Database Query で多数の機能強化が実施されました。中でも重要な変更として、Azure SQL Database でデータベース間のクエリが新たにサポートされるようになりました。これにより、リモート テーブルからローカル テーブルへの SELECT など、一般的なデータベース間のクエリ タスクが可能になります。

また、次の図に示すような、多数のデータベースが相互のテーブルにアクセスする必要がある高度なリモート データベース クエリ トポロジも実現可能になります。

この新しいデータベース間のクエリ機能により、Elastic Database Query で既にサポートされている水平方向のパーティション分割 (シャーディング、下図参照) が補完されます。

オンプレミス版の SQL Server とは異なり、Azure SQL Database の Elastic Database Query では垂直方向と水平方向のパーティション分割が 1 つの共通概念に従って統合され、同一の対象に使用できるようになりました。

プレビュー版 Elastic Database Query の最新の更新では、下記の機能強化が実施されています。

  • シャーディングを行わないデータベース間のクエリの一般的なシナリオのサポートが強化されました。
  • Elastic Database Query が Standard と Premium の両方のパフォーマンス レベルで使用可能になりました。
  • DDL の柔軟性が向上し、リモート データベース テーブルを表すためにスキーマおよびテーブル名のエイリアスを使用できるようになりました。
  • リモート テーブルを参照するときに T-SQL パラメーターを使用するクエリのパフォーマンスが大幅に向上しました。
  • リモート データベースから大量の行を取得するクエリのパフォーマンスが向上しました。
  • sp_execute_fanout プロシージャのパラメーターがサポートされました。

今回の機能強化の詳細については、以下のセクションをお読みください。

リモート データベースに対するクエリの実行

Elastic Database Query では、外部データ ソースおよび外部テーブル用の DDL (データ定義言語) の簡単な拡張機能を使用して、リモートの Azure SQL Database のテーブルにアクセスできるようになりました。これにより、外部データ ソースを定義することで、データ層のすべてのデータベース間で共有されている参照データを格納するリモート データベースにアクセスできるようになります。また、INSERT INTO... SELECT ステートメントを使用すると、テーブルの内容をリモート データベースから他のデータベースに簡単にコピーできます。

単一のリモート データベースを参照する外部データ ソースは、次の DDL ステートメントで TYPE 句に RDBMS オプションを指定することで識別されます。

 CREATE EXTERNAL DATA SOURCE RemoteReferenceData
WITH
(
  TYPE=RDBMS,
 LOCATION='myserver.database.windows.net',
   DATABASE_NAME='ReferenceData',
  CREDENTIAL= SqlUser
);

上記の外部データ ソースを基に、ReferenceData データベースの zipcode テーブルへのリモート アクセスを提供する外部テーブルを定義できます。

 CREATE EXTERNAL TABLE [dbo].[zipcode](
    [zc_id] int NOT NULL,
   [zc_cityname] nvarchar(256) NULL,
   [zc_zipcode] nvarchar(20) NOT NULL,
 [zc_country] nvarchar(5) NOT NULL
)
WITH
(
 DATA_SOURCE = RemoteReferenceData
);

この簡単な設定を一度行うだけで、外部データ ソースと外部テーブルが定義された任意の Azure SQL Database からリモートの zipcode テーブルにクエリがアクセスできるようになります。

使用可能なパフォーマンス レベルの拡大

Elastic Database Query を Azure SQL Database の Standard パフォーマンス レベルでも使用できるようになりました。これにより、Azure SQL Database でデータベース間のクエリおよびパーティション分割の使用するための導入コストが大幅に削減されました。Standard レベルでは DTU の上限が低いため、初めてリモート データベースに対するクエリを実行する際には、Elastic Database Query の初期化に最大 1 分かかる場合があります。Elastic Database Query の初期化の所要時間の短縮については現在積極的に取り組んでおり、今後数か月以内に改善される予定です。

命名規則の柔軟性の向上

一部の重要なシナリオでは、外部テーブルにリモート データベースの元のテーブルとは異なる名前を付ける必要があります。たとえば、リモート テーブルと同じ名前のローカル テーブルが既に存在している場合などが該当します。このような場合は、リモート テーブル名にエイリアスを使用する必要があります。

たとえば、外部テーブルを定義して、水平方向にパーティション分割された (シャーディングされた) データ層全体で DMV (動的管理ビュー) を統合する場合について考えてみましょう。そのためには、これまでは各リモート データベースのビューを使用して DMV の名前を変更し、外部テーブルの定義からビューを参照するなど、複雑な対応が必要でした。これは、DMV 名またはカタログ名が既にローカルに存在し、外部テーブル名としてそのまま使用することができなかったことが原因です。

今後は、外部テーブル名として任意の名前を使用し、外部テーブルの DDL で新しい OBJECT_SCHEMA 句と OBJECT_NAME 句を使用して元のリモート テーブルを識別することができます。これにより、以下に示す例のように、スケールアウト データ層の DMV またはカタログ ビューに対して簡単にクエリを実行できるようになります。次の DDL は、外部データ ソースと外部テーブルの設定を一度だけ行うものです。外部テーブルの定義に OBJECT_SCHEMA 句と OBJECT_NAME 句が使用されている点に注目してください。

 CREATE EXTERNAL DATA SOURCE MyExtSrc
WITH
(
 TYPE=SHARD_MAP_MANAGER,
 LOCATION='myserver.database.windows.net',
   DATABASE_NAME='ShardMapDatabase',
   CREDENTIAL= SMMUser,
    SHARD_MAP_NAME='ShardMap'
);

 

 CREATE EXTERNAL TABLE [dbo].[all_dm_exec_requests](
   [session_id] smallint NOT NULL,
 [request_id] int NOT NULL,
  [start_time] datetime NOT NULL, 
    [status] nvarchar(30) NOT NULL,
 [command] nvarchar(32) NOT NULL,
    [sql_handle] varbinary(64),
 [statement_start_offset] int,
   [statement_end_offset] int,
 [cpu_time] int NOT NULL
)
WITH
(
   DATA_SOURCE = MyExtSrc,
 SCHEMA_NAME = 'sys',
    OBJECT_NAME = 'dm_exec_requests',
   DISTRIBUTION=ROUND_ROBIN
);

これで、以下のように Elastic Database Query を使用して、非常に負荷のかかる要求をデータ層全体から簡単に取得できます。

 SELECT TOP 10 
    [request_id],
   [start_time]
    [status],
   [command]
FROM all_dm_exec_requests
ORDER BY [cpu_time] DESC

sp_execute_fanout の新しい署名

Elastic Database Query では、sp_execute_fanout ストアド プロシージャを使用して、リモート データベースのストアド プロシージャと関数を呼び出すことができます。最近の Azure SQL Database の機能強化により、sp_execute_fanout の署名がなじみのある sp_executesql の署名に沿ったものになりました。これにより、sp_execute_fanout の呼び出しに一般的な SQL パラメーターを渡すことが可能になります。この機能は近日中に提供が開始される予定です。

パフォーマンスの強化

これまで、Elastic Database Query ではパラメーター化された処理をリモート データベースにプッシュすることはできませんでした。そのため、ときには大規模な行の集合を不必要にローカルに移動して、これらの処理を評価する必要がありました。しかし、今回の機能強化により、パラメーター化された処理をリモート データベースにプッシュし、リモートで評価できるようになりました。次の例のように、外部テーブルやローカル テーブルに対してクエリを実行すると、リモート データベースで WHERE 句のフィルターを選択的に評価できるため、非常に多数の行を転送する必要がなくなります。

 DECLARE @low int
DECLARE @high int
SET @low = 100
SET @high = 200

SELECT c.CustomerId, c.Name, count(OrderId) 
FROM remote_customers c
JOIN local_orders o
ON c.CustomerId = o.CustomerId 
WHERE c.CustomerId > @low and c.CustomerId < @high
GROUP BY c.CustomerId, c.Name

上記のクエリのクエリ プランを確認すると、WHERE 句で指定された CustomerID の範囲がリモート クエリの演算子に正常に反映されていることがわかります。

最後になりますが、Elastic Database Query を使用して短い行を大量に転送する処理も効率化されました。マイクロソフトのテストでは、外部テーブルに対するクエリによって 10 万行以上を転送する場合、パフォーマンスが 5 倍以上に向上したことが実証されています。

この記事でご紹介した機能強化の詳細については、Elastic Database Query の概要をご覧ください。