Поддерживает ли MS-SQL таблицы в памяти? - PullRequest
16 голосов
/ 26 августа 2008

Недавно я начал изменять некоторые из наших приложений для поддержки MS SQL Server в качестве альтернативного бэкэнда.

Одной из проблем совместимости, с которой я столкнулся, является использование MySQL CREATE TEMPORARY TABLE для создания таблиц в памяти, которые хранят данные для очень быстрого доступа во время сеанса без необходимости постоянного хранения.

Что такое эквивалент в MS SQL?

Требуется, чтобы я мог использовать временную таблицу точно так же, как и любую другую, особенно JOIN с постоянными.

Ответы [ 8 ]

18 голосов
/ 26 августа 2008

Вы можете создать переменные таблицы (в памяти) и два разных типа временной таблицы:

--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)
)

Edit:

После обратной связи я думаю, что это требует небольшого уточнения.

#table и ##table всегда будут в TempDB.

@Table переменные обычно хранятся в памяти, но это не гарантируется. SQL решает на основе плана запроса и использует TempDB, если это необходимо.

13 голосов
/ 26 августа 2008

@ Keith

Это распространенное заблуждение: переменные таблицы НЕ обязательно хранятся в памяти. Фактически, SQL Server решает, сохранять ли переменную в памяти или передавать ее в TempDB. Не существует надежного способа (по крайней мере, в SQL Server 2005) гарантировать, что данные таблицы хранятся в памяти. Для более подробной информации смотрите здесь

3 голосов
/ 26 августа 2008

В SQL Server 2005 можно объявить «табличную переменную», например:

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

Затем вы ссылаетесь на него как на переменную:

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

Нет необходимости отбрасывать его - он исчезает, когда переменная выходит из области видимости.

2 голосов
/ 11 января 2015

Это возможно с 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
1 голос
/ 10 июня 2009

Я понимаю, чего вы пытаетесь достичь. Добро пожаловать в мир разнообразных баз данных!

SQL Server 2000 поддерживает временные таблицы, созданные путем добавления префикса # к имени таблицы, превращения его в локально доступную временную таблицу (локальную для сеанса) и предшествующего ## имени таблицы, для глобально доступных временных таблиц, например #MyLocalTable и ## MyGlobalTable соответственно.

SQL Server 2005 и выше поддерживают как временные таблицы (локальные, глобальные), так и переменные таблиц - обратите внимание на новые функциональные возможности переменных таблиц в SQL 2008 и выпустите две! Разница между временными таблицами и табличными переменными не так велика, но заключается в способе обработки сервером базы данных.

Я бы не хотел говорить о более старых версиях SQL-сервера, таких как 7, 6, хотя я работал с ними, и это то, откуда я пришел: -)

Принято считать, что переменные таблицы всегда находятся в памяти, но это неправильно. В зависимости от использования памяти и объема транзакций сервера базы данных страницы табличной переменной могут быть экспортированы из памяти и записаны в базу данных tempdb, а остальная часть обработки выполняется там (в базе данных tempdb).

Обратите внимание, что база данных tempdb является экземпляром, в котором нет постоянных объектов, но она отвечает за обработку рабочих нагрузок, связанных с побочными транзакциями, такими как сортировка и другая обработка, которая носит временный характер. С другой стороны, переменные таблицы (обычно с меньшими данными) хранятся в памяти (ОЗУ), что делает их более быстрым доступом и, следовательно, меньшим дисковым вводом-выводом с точки зрения использования диска tempdb при использовании переменных таблицы с меньшими данными по сравнению с временными таблицами, которые всегда войти в базу данных tempdb.

Переменные таблиц нельзя индексировать, в то время как временные таблицы (как локальные, так и глобальные) можно индексировать для ускорения обработки в случае большого объема данных. Таким образом, вы знаете свой выбор в случае более быстрой обработки с большими объемами данных с помощью временных транзакций. Также стоит отметить, что транзакции только для переменных таблицы не регистрируются и не могут быть откатлены, в то время как транзакции, выполненные во временных таблицах, могут быть откатлены!

Таким образом, переменные таблицы лучше подходят для небольших данных, в то время как временные таблицы лучше для временных данных, которые обрабатываются временно. Если вам также необходимо надлежащее управление транзакциями с использованием блоков транзакций, переменные таблиц не подходят для отката транзакций, поэтому в этом случае лучше использовать временные таблицы.

Наконец, временные таблицы всегда увеличивают дисковый ввод-вывод, поскольку они всегда используют базу данных tempdb, в то время как переменные таблицы могут не увеличивать ее в зависимости от уровней нагрузки на память.

Дайте мне знать, если вы хотите получить советы о том, как настроить базу данных tempdb, чтобы получить гораздо более высокую производительность и превысить 100%!

1 голос
/ 26 августа 2008

Хороший пост в блоге здесь , но в основном префикс локальных временных таблиц с # и глобальный темп с ## - например,

CREATE TABLE #localtemp
0 голосов
/ 26 августа 2008

Синтаксис, который вы хотите:

создать таблицу # tablename

Префикс # определяет таблицу как временную таблицу.

0 голосов
/ 26 августа 2008

CREATE TABLE # tmptablename

Используйте префикс знака хеш / фунт

...