MS-SQL はインメモリ テーブルをサポートしていますか?
-
09-06-2019 - |
質問
最近、いくつかのアプリケーションをサポートするように変更し始めました。 MS SQL Server
代替バックエンドとして。
私が遭遇した互換性の問題の 1 つは、MySQL の CREATE TEMPORARY TABLE を使用して、永続ストレージを必要とせずにセッション中に非常に高速にアクセスできるデータを保持するメモリ内テーブルを作成することです。
MS SQL でこれに相当するものは何ですか?
要件としては、一時テーブルを他のものと同じように使用できる必要があることです。特に、 JOIN
それは永久的なものと一緒です。
解決
@キース
これはよくある誤解です。テーブル変数は必ずしもメモリに格納されるわけではありません。実際、SQL Server は変数をメモリ内に保持するか、TempDB にスピルするかを決定します。(少なくとも SQL Server 2005 では) テーブル データをメモリ内に確実に保持する信頼できる方法はありません。さらに詳しい情報については、こちらをご覧ください ここ
他のヒント
テーブル変数 (メモリ内) と 2 つの異なるタイプの一時テーブルを作成できます。
--visible only to me, in memory (SQL 2000 and above only)
declare @test table (
Field1 int,
Field2 nvarchar(50)
);
--visible only to me, stored in tempDB
create table #test (
Field1 int,
Field2 nvarchar(50)
)
--visible to everyone, stored in tempDB
create table ##test (
Field1 int,
Field2 nvarchar(50)
)
編集:
フィードバックを受けて、これについては少し説明が必要だと思います。
#table
そして ##table
は常に TempDB にあります。
@Table
変数は通常メモリ内に存在しますが、メモリ内に存在することが保証されているわけではありません。SQL はクエリ プランに基づいて決定し、必要に応じて TempDB を使用します。
SQL Server 2005 では、次のように「テーブル変数」を宣言できます。
declare @foo table (
Id int,
Name varchar(100)
);
次に、それを変数と同じように参照します。
select * from @foo f
join bar b on b.Id = f.Id
削除する必要はありません。変数がスコープ外になると削除されます。
MS SQL Server 2014であれば可能です。
見る: http://msdn.microsoft.com/en-us/library/dn133079.aspx
SQL 生成コードの例を次に示します (MSDN から)。
-- create a database with a memory-optimized filegroup and a container.
CREATE DATABASE imoltp
GO
ALTER DATABASE imoltp ADD FILEGROUP imoltp_mod CONTAINS MEMORY_OPTIMIZED_DATA
ALTER DATABASE imoltp ADD FILE (name='imoltp_mod1', filename='c:\data\imoltp_mod1') TO FILEGROUP imoltp_mod
ALTER DATABASE imoltp SET MEMORY_OPTIMIZED_ELEVATE_TO_SNAPSHOT=ON
GO
USE imoltp
GO
-- create a durable (data will be persisted) memory-optimized table
-- two of the columns are indexed
CREATE TABLE dbo.ShoppingCart (
ShoppingCartId INT IDENTITY(1,1) PRIMARY KEY NONCLUSTERED,
UserId INT NOT NULL INDEX ix_UserId NONCLUSTERED HASH WITH (BUCKET_COUNT=1000000),
CreatedDate DATETIME2 NOT NULL,
TotalPrice MONEY
) WITH (MEMORY_OPTIMIZED=ON)
GO
-- create a non-durable table. Data will not be persisted, data loss if the server turns off unexpectedly
CREATE TABLE dbo.UserSession (
SessionId INT IDENTITY(1,1) PRIMARY KEY NONCLUSTERED HASH WITH (BUCKET_COUNT=400000),
UserId int NOT NULL,
CreatedDate DATETIME2 NOT NULL,
ShoppingCartId INT,
INDEX ix_UserId NONCLUSTERED HASH (UserId) WITH (BUCKET_COUNT=400000)
) WITH (MEMORY_OPTIMIZED=ON, DURABILITY=SCHEMA_ONLY)
GO
良い ブログ投稿はこちら ただし、基本的にローカル一時テーブルには # を、グローバル一時テーブルには ## をプレフィックスとして付けます。
CREATE TABLE #localtemp
あなたが何を達成しようとしているのか理解しています。多彩なデータベースの世界へようこそ!
SQL Server 2000 は、テーブル名に # を接頭辞として付けて、ローカルでアクセス可能な一時テーブル (セッションに対してローカル) にし、グローバルにアクセス可能な一時テーブル (#MyLocalTable や ##MyGlobalTable など) の場合は、テーブル名の前に ## を付けて作成された一時テーブルをサポートします。それぞれ。
SQL Server 2005 以降では、一時テーブル (ローカル、グローバル) とテーブル変数の両方がサポートされています。SQL 2008 およびリリース 2 のテーブル変数の新機能に注意してください。一時テーブルとテーブル変数の違いはそれほど大きくはありませんが、データベース サーバーがそれらを処理する方法にあります。
7 や 6 などの古いバージョンの SQL Server については話したくないのですが、私はそれらのバージョンで仕事をしたことがありますし、とにかくそれが私の原点です :-)
テーブル変数は常にメモリ内に存在すると考えられがちですが、これは間違いです。メモリ使用量とデータベース サーバーのトランザクション量に応じて、テーブル変数のページがメモリからエクスポートされて tempdb に書き込まれ、残りの処理がそこで (tempdb 内で) 行われることがあります。
tempdb は、本質的に永続的なオブジェクトを持たないインスタンス上のデータベースですが、並べ替えなどのサイド トランザクションを含むワークロードや、本質的に一時的なその他の処理作業を処理する責任があることに注意してください。一方、テーブル変数 (通常はデータが小さい) はメモリ (RAM) に保持されるため、アクセスが速くなり、常に一時テーブルを使用する場合と比較して、データが小さいテーブル変数を使用すると、tempdb ドライブの使用に関するディスク IO が少なくなります。 tempdbにログインします。
テーブル変数にはインデックスを作成できませんが、データ量が多い場合に処理を高速化するために、一時テーブル (ローカルとグローバルの両方) にはインデックスを作成できます。したがって、一時的なトランザクションによる大量のデータをより高速に処理する場合の選択がわかります。また、テーブル変数のみのトランザクションはログに記録されずロールバックできないが、一時テーブルで実行されたトランザクションはロールバックできることにも注意してください。
要約すると、テーブル変数は小さなデータの場合に適しており、一時テーブルは一時的に処理される大きなデータの場合に適しています。トランザクション ブロックを使用して適切なトランザクション制御も必要な場合は、テーブル変数はトランザクションをロールバックするためのオプションではないため、この場合は一時テーブルを使用することをお勧めします。
最後に、一時テーブルは常に tempdb を使用するため、ディスク IO が常に増加しますが、テーブル変数はメモリのストレス レベルに応じて増加しない可能性があります。
tempdb を調整して 100% を超えるパフォーマンスを実現するためのヒントが必要な場合は、お知らせください。
必要な構文は次のとおりです。
テーブル #tablename を作成します
# プレフィックスは、テーブルが一時テーブルであることを示します。
テーブルの作成 #tmptablename
ハッシュ/ポンド記号の接頭辞を使用する