Недавно я начал изменять некоторые из наших приложений для поддержки MS SQL Server в качестве альтернативной серверной части.
Одна из проблем совместимости, с которой я столкнулся, - это использование MySQL CREATE TEMPORARY TABLE для создания таблиц в памяти, которые содержат данные для очень быстрого доступа во время сеанса без необходимости постоянного хранения.
Что эквивалентно в MS SQL?
Требование состоит в том, что мне нужно иметь возможность использовать временную таблицу, как и любую другую, особенно JOIN с постоянными.






СОЗДАТЬ ТАБЛИЦУ #tmptablename
Используйте префикс знака решетки / решетки
Вы можете объявить «табличную переменную» в SQL Server 2005 следующим образом:
declare @foo table (
Id int,
Name varchar(100)
);
Затем вы обращаетесь к нему как к переменной:
select * from @foo f
join bar b on b.Id = f.Id
Не нужно его отбрасывать - он исчезает, когда переменная выходит за пределы области видимости.
Желаемый синтаксис:
создать таблицу #tablename
Префикс # определяет таблицу как временную.
Хороший сообщение в блоге здесь, но в основном префикс локальных временных таблиц с # и глобальных временных с ## - например
CREATE TABLE #localtemp
Вы можете создавать табличные переменные (в памяти) и два разных типа временных таблиц:
--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.
@Keith
Это распространенное заблуждение: переменные таблицы НЕ обязательно хранятся в памяти. Фактически SQL Server решает, сохранить ли переменную в памяти или передать ее TempDB. Нет надежного способа (по крайней мере, в SQL Server 2005) гарантировать, что данные таблицы хранятся в памяти. Подробнее смотрите здесь
Я понимаю, чего вы пытаетесь достичь. Добро пожаловать в мир разнообразных баз данных!
SQL server 2000 поддерживает временные таблицы, созданные путем добавления префикса # к имени таблицы, что делает ее локальной временной таблицей (локальной для сеанса) и предшествующей ## имени таблицы, для глобально доступных временных таблиц, например #MyLocalTable и ## MyGlobalTable соответственно.
SQL Server 2005 и более поздние версии поддерживают как временные таблицы (локальные, глобальные), так и табличные переменные - обратите внимание на новые функции для табличных переменных в SQL 2008 и второй версии! Разница между временными таблицами и табличными переменными не так велика, но заключается в способе их обработки сервером базы данных.
Я бы не хотел говорить о более старых версиях SQL-сервера, таких как 7, 6, хотя я работал с ними, и все равно откуда я пришел :-)
Принято считать, что переменные таблицы всегда находятся в памяти, но это неверно. В зависимости от использования памяти и объема транзакций сервера базы данных, страницы табличной переменной могут быть экспортированы из памяти и записаны в tempdb, а остальная часть обработки происходит там (в tempdb).
Обратите внимание, что tempdb - это база данных в экземпляре без постоянных объектов по своей природе, но она отвечает за обработку рабочих нагрузок, связанных с побочными транзакциями, такими как сортировка, и другой обработкой, которая носит временный характер. С другой стороны, табличные переменные (обычно с меньшими данными) хранятся в памяти (ОЗУ), что ускоряет доступ к ним и, следовательно, уменьшает дисковый ввод-вывод с точки зрения использования диска tempdb при использовании табличных переменных с меньшими данными по сравнению с временными таблицами, которые всегда войдите в tempdb.
Табличные переменные не могут быть проиндексированы, в то время как временные таблицы (как локальные, так и глобальные) могут индексироваться для более быстрой обработки в случае большого количества данных. Таким образом, вы знаете свой выбор в случае более быстрой обработки больших объемов данных временными транзакциями. Также стоит отметить, что транзакции только с табличными переменными не регистрируются и не могут быть отменены, в то время как транзакции, выполненные с временными таблицами, могут быть отменены!
Таким образом, переменные таблицы лучше подходят для небольших данных, в то время как временные таблицы лучше для временно обрабатываемых больших данных. Если вам также нужен надлежащий контроль транзакций с использованием блоков транзакций, переменные таблицы не подходят для отката транзакций, поэтому в этом случае вам лучше использовать временные таблицы.
Наконец, временные таблицы всегда будут увеличивать дисковый ввод-вывод, поскольку они всегда используют tempdb, а переменные таблицы могут не увеличивать его, в зависимости от уровней нагрузки на память.
Дайте мне знать, если вам нужны советы о том, как настроить вашу базу данных tempdb, чтобы добиться гораздо более высокой производительности, чтобы она превысила 100%!
Крис, почему бы вам не создать учетную запись SO?
@Chris - пожалуйста, оставьте религиозные теги в конце вашего сообщения. Кроме того, материалы для саморекламы должны находиться в вашем профиле, а не в конце вашего сообщения.
Это возможно с 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
Надеюсь, вы знаете, что в MySQL временные таблицы, созданные пользователем, по умолчанию не хранятся в памяти! Только если вы укажете ENGINE = MEMORY в операторе CREATE TABLE, таблица будет в памяти. В противном случае временная таблица будет создана с использованием механизма хранения по умолчанию, которым, скорее всего, является MyISAM или INNODB, и сохранена на диске. Не путайте созданные пользователем с внутренними временными таблицами, которые создаются MySQL во время сложных соединений. По возможности они создаются в памяти.