Поддерживает ли MS-SQL таблицы в памяти?
-
09-06-2019 - |
Вопрос
Недавно я начал менять некоторые наши приложения для поддержки MS SQL Server
как альтернативный бэкэнд.
Одна из проблем совместимости, с которой я столкнулся, — это использование MySQL CREATE TEMPORARY TABLE для создания таблиц в памяти, которые содержат данные для очень быстрого доступа во время сеанса без необходимости постоянного хранения.
Что такое эквивалент в MS SQL?
Требование состоит в том, что я должен иметь возможность использовать временную таблицу так же, как и любую другую, особенно JOIN
это с постоянными.
Решение
@Кит
Это распространенное заблуждение:Табличные переменные НЕ обязательно хранятся в памяти.Фактически SQL Server решает, хранить ли переменную в памяти или передать ее в TempDB.Не существует надежного способа (по крайней мере, в SQL Server 2005) гарантировать, что данные таблицы хранятся в памяти.Для более подробной информации смотрите здесь
Другие советы
Вы можете создавать табличные переменные (в памяти) и два разных типа временных таблиц:
--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 и втором выпуске!Разница между временными таблицами и табличными переменными не так уж велика, но заключается в том, как с ними обращается сервер базы данных.
Я бы не хотел говорить о более старых версиях SQL-сервера, таких как 7, 6, хотя я работал с ними и все равно оттуда пришел :-)
Принято думать, что табличные переменные всегда находятся в памяти, но это неверно.В зависимости от использования памяти и объема транзакций сервера базы данных страницы табличной переменной могут быть экспортированы из памяти и записаны в базу данных tempdb, а остальная обработка происходит там (в базе данных tempdb).
Обратите внимание, что tempdb — это база данных в экземпляре, не имеющая постоянных объектов по своей природе, но она отвечает за обработку рабочих нагрузок, включающих побочные транзакции, такие как сортировка, и другие работы по обработке, которые по своей природе являются временными.С другой стороны, табличные переменные (обычно с меньшими данными) хранятся в памяти (ОЗУ), что ускоряет доступ к ним и, следовательно, снижает дисковые операции ввода-вывода с точки зрения использования диска tempdb при использовании табличных переменных с меньшими данными по сравнению с временными таблицами, которые всегда войдите в базу данных tempdb.
Табличные переменные не могут быть проиндексированы, тогда как временные таблицы (как локальные, так и глобальные) могут быть проиндексированы для более быстрой обработки в случае большого объема данных.Таким образом, вы знаете свой выбор в случае более быстрой обработки больших объемов данных посредством временных транзакций.Также стоит отметить, что транзакции только с табличными переменными не протоколируются и не могут быть отменены, в то время как транзакции, выполненные с временными таблицами, могут быть отменены!
Таким образом, табличные переменные лучше подходят для небольших данных, а временные таблицы лучше для больших данных, обрабатываемых временно.Если вам также нужен правильный контроль транзакций с использованием блоков транзакций, табличные переменные не подходят для отката транзакций, поэтому в этом случае вам лучше использовать временные таблицы.
Наконец, временные таблицы всегда увеличивают объем дискового ввода-вывода, поскольку они всегда используют базу данных tempdb, в то время как табличные переменные могут не увеличивать его, в зависимости от уровня нагрузки на память.
Дайте мне знать, если вам нужны советы о том, как настроить базу данных tempdb, чтобы повысить производительность и превысить 100 %.
Синтаксис, который вам нужен:
создать таблицу #имя_таблицы
Префикс # идентифицирует таблицу как временную.
СОЗДАТЬ ТАБЛИЦУ #tmptablename
Используйте префикс знака решётки/решетки.