17

最近、MS SQL Server代替バックエンドとしてサポートするために、いくつかのアプリケーションを変更し始めました。

私が遭遇した互換性の問題の 1 つは、MySQL の CREATE TEMPORARY TABLE を使用して、永続的なストレージを必要とせずにセッション中に非常に高速にアクセスするためのデータを保持するインメモリ テーブルを作成することです。

MS SQL で同等のものは何ですか?

要件は、一時テーブルを他のテーブルと同じように、特にJOIN永続テーブルと同じように使用できる必要があることです。

4

8 に答える 8

19

テーブル変数 (メモリ内) と、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 を使用します。

于 2008-08-26T12:10:52.343 に答える
13

@キース

これはよくある誤解です。テーブル変数は必ずしもメモリに格納されるとは限りません。実際、SQL Server は、変数をメモリに保持するか、TempDB にスピルするかを決定します。(少なくとも SQL Server 2005 では) テーブル データを確実にメモリに保持する確実な方法はありません。より詳細な情報については、こちらをご覧ください

于 2008-08-26T12:29:08.850 に答える
3

次のように、SQL Server 2005 で「テーブル変数」を宣言できます。

declare @foo table (
    Id int,
    Name varchar(100)
);

次に、変数のように参照します。

select * from @foo f
    join bar b on b.Id = f.Id

ドロップする必要はありません。変数がスコープ外になると消えます。

于 2008-08-26T12:07:21.523 に答える
2

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
于 2015-01-11T10:34:45.060 に答える
1

あなたが達成しようとしていることを理解しています。ようこそ、多種多様なデータベースの世界へ!

SQL Server 2000 は、グローバルにアクセス可能な一時テーブル (#MyLocalTable や ##MyGlobalTable など) に対して、テーブル名の前に # を付けてローカルでアクセス可能な (セッションに対してローカルな) 一時テーブルにし、テーブル名の前に ## を付けて作成された一時テーブルをサポートしています。それぞれ。

SQL Server 2005 以降では、一時テーブル (ローカル、グローバル) とテーブル変数の両方がサポートされています。SQL 2008 とリリース 2 のテーブル変数の新機能に注意してください! 一時テーブルとテーブル変数の違いはそれほど大きくはありませんが、データベース サーバーがそれらを処理する方法にあります。

7、6 のような古いバージョンの SQL サーバーについては話したくありませんが、私はそれらを使用しており、とにかくそれが私の出身地です :-)

テーブル変数は常にメモリ内にあると考えるのが一般的ですが、これは誤りです。メモリ使用量とデータベース サーバーのトランザクション量によっては、テーブル変数のページがメモリからエクスポートされて tempdb に書き込まれ、残りの処理がそこで (tempdb で) 行われる場合があります。

tempdb は、本質的に永続的なオブジェクトを持たないインスタンス上のデータベースですが、並べ替えなどのサイド トランザクションを含むワークロードや、本質的に一時的なその他の処理作業を処理する責任があることに注意してください。一方、テーブル変数 (通常は小さいデータを含む) はメモリ (RAM) に保持されるため、アクセスが高速化されるため、一時テーブルと比較して小さいデータを含むテーブル変数を使用する場合、tempdb ドライブを使用することでディスク IO が少なくなります。 tempdb にログインします。

テーブル変数にはインデックスを作成できませんが、一時テーブル (ローカルとグローバルの両方) にはインデックスを作成して、データ量が多い場合の処理​​を高速化できます。したがって、一時的なトランザクションによって大量のデータを高速処理する場合の選択がわかります。テーブル変数のみのトランザクションはログに記録されず、一時テーブルで行われたトランザクションはロールバックできますが、ロールバックできないことにも注意してください。

要約すると、テーブル変数は小さなデータに適していますが、一時テーブルは一時的に処理される大きなデータに適しています。トランザクション ブロックを使用した適切なトランザクション制御も必要な場合、テーブル変数はトランザクションをロールバックするためのオプションではないため、この場合は一時テーブルを使用することをお勧めします。

最後に、一時テーブルは常に tempdb を使用するため、ディスク IO は常に増加しますが、メモリ ストレス レベルによっては、テーブル変数はそれを増加させない場合があります。

tempdb を調整して 100% を超えるパフォーマンスを実現するためのヒントが必要な場合はお知らせください。

于 2009-06-10T17:34:56.323 に答える
1

ここに良いブログ投稿がありますが、基本的にローカル一時テーブルには # を、グローバル一時テーブルには ## をプレフィックスとして付けます - 例

CREATE TABLE #localtemp
于 2008-08-26T12:10:33.310 に答える
0

CREATE TABLE #tmpテーブル名

ハッシュ/ポンド記号のプレフィックスを使用する

于 2008-08-26T12:06:59.030 に答える
0

必要な構文は次のとおりです。

テーブル #tablename を作成

# プレフィックスは、テーブルを一時テーブルとして識別します。

于 2008-08-26T12:08:14.970 に答える