MS-SQL是否支持内存表?

时间:2008-08-26 12:03:44

标签: mysql sql-server rdbms portability

最近,我开始将一些应用程序更改为支持MS SQL Server作为替代后端。

我遇到的一个兼容性问题是使用MySQL的CREATE TEMPORARY TABLE来创建内存表,这些表可以在会话期间保存数据以实现非常快速的访问,而不需要永久存储。

MS SQL中的等价物是什么?

要求是我需要能够像使用其他任何临时表一样使用临时表,尤其是JOIN它与永久表。

8 个答案:

答案 0 :(得分:18)

您可以创建表变量(在内存中)和两种不同类型的临时表:

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

答案 1 :(得分:13)

@Keith

这是一种常见的误解:表变量不一定存储在内存中。事实上,SQL Server决定是将变量保留在内存中还是将其溢出到TempDB。没有可靠的方法(至少在SQL Server 2005中)确保表数据保存在内存中。有关详细信息,请查看here

答案 2 :(得分:3)

您可以在SQL Server 2005中声明“表变量”,如下所示:

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

然后你就像变量一样引用它:

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

无需丢弃它 - 当变量超出范围时它会消失。

答案 3 :(得分: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

答案 4 :(得分:1)

一个好的blog post here,但基本上是带#和全局temp的本地临时表的前缀## - 例如

CREATE TABLE #localtemp

答案 5 :(得分:1)

我理解你想要实现的目标。欢迎来到各种数据库的世界!

SQL Server 2000支持通过在表名前加上#来创建临时表,使其成为本地可访问的临时表(会话本地)和表名前面的##,用于全局可访问的临时表,例如#MyLocalTable和## MyGlobalTable分别。

SQL Server 2005及更高版本支持临时表(本地,全局)和表变量 - 在SQL 2008和版本2中注意表变量的新功能!临时表和表变量之间的区别并不大,而在于数据库服务器处理它们的方式。

我不想谈论像旧版本的SQL服务器,例如7,6,虽然我已经和他们一起工作了,但我仍然来自这里: - )

通常认为表变量总是驻留在内存中,但这是错误的。根据内存使用情况和事务的数据库服务器量,表变量的页面可以从内存中导出并在tempdb中写入,其余的处理在那里进行(在tempdb中)。

请注意,tempdb是一个实例上的数据库,本质上没有永久对象,但它负责处理涉及诸如排序等临时事务的工作负载以及其他暂时性的处理工作。另一方面,表变量(通常具有较小的数据)保存在内存(RAM)中,使得访问速度更快,因此在使用具有较小数据的表变量时使用tempdb驱动器的磁盘IO较少,而临时表总是如此登录tempdb。

如果数据量很大,则可以索引临时表(本地和全局)以便更快地处理表变量。因此,您可以通过临时事务更快地处理更大的数据量,从而了解您的选择。还值得注意的是,单独的表变量上的事务不会被记录,并且无法回滚,而在临时表上完成的事务可以回滚!

总之,表变量对于较小的数据更好,而临时表对于临时处理的较大数据更好。如果您还希望使用事务块进行适当的事务控制,则表变量不是回滚事务的选项,因此在这种情况下您最好使用临时表。

最后,临时表总是会增加磁盘IO,因为它们总是使用tempdb,而表变量可能不会增加它,具体取决于内存压力级别。

如果您想了解如何调整tempdb以获得更快的性能以超过100%,请告诉我们。

答案 6 :(得分:0)

CREATE TABLE #tmptablename

使用哈希/井号前缀

答案 7 :(得分:0)

您想要的语法是:

创建表#tablename

#prefix将表标识为临时表。