2008-08-26 139 views
16

最近,我开始改变一些我们的应用程序来支持MS SQL Server作为替代后端。MS-SQL是否支持内存表?

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

MS SQL中的等效项是什么?

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

+1

我希望你知道在MySQL中,用户创建的临时表默认情况下不在内存中!只有在CREATE TABLE语句中指定ENGINE = MEMORY时,该表才会在内存中。否则,临时表将使用默认存储引擎(很可能是MyISAM或INNODB)创建,并保存在磁盘上。 不要将用户创建的内部临时表与复杂连接期间由MySQL创建的临时表混淆。如果可能的话,那些内存中创建。 – 2014-05-20 11:39:18

回答

13

@Keith

这是一种常见的误解:表变量不一定存储在存储器中。实际上,SQL Server决定是将变量保存在内存中还是将其泄露到TempDB中。没有可靠的方法(至少在SQL Server 2005中)来确保表数据保存在内存中。欲了解更详细的信息外观here

0

CREATE TABLE #tmptablename

使用哈希/英镑符号前缀

3

可以在SQL Server 2005中申报了 “表变量”,像这样:

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

然后你参考它就像一个变量:

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

没有必要放弃它 - 它消失时,日e变量超出范围。

0

你想要的语法是:

创建表#tablename

#前缀标识表作为临时表。

1

与#和##与全球气温好的blog post here但基本上前缀本地临时表 - 例如

CREATE TABLE #localtemp 
17

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

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

我明白你想达到什么。欢迎来到各种数据库的世界!

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

SQL Server 2005及以上版本支持两种临时表(本地和全球)和表变量 - 注意在表变量上的新功能在SQL 2008和发布两个!临时表和表变量之间的区别不是很大,而在于数据库服务器处理它们的方式。

我不希望谈旧版本像7,6 SQL服务器的,虽然我已经与他们合作,它是我来自哪里反正来了:-)

是很普遍认为,表变量一直驻留在记忆中,但这是错误的。根据内存使用情况和事务的数据库服务器量,可以从内存中导出表变量的页面,并将其写入tempdb中,其余处理将在此处进行(在tempdb中)。

请注意,tempdb数据库是与自然界中没有永久对象实例的数据库,但它负责处理涉及方交易物品分拣的工作量,和其他处理工作,这在本质上是暂时的。另一方面,表格变量(通常数据较小)保存在内存(RAM)中,使其访问速度更快,因此在使用tempdb驱动器时,使用小型数据表变量与临时表登录tempdb。

表变量不能被索引而临时表(本地和全局)的情况下可以编入索引的更快的处理的数据量是大的。所以,如果通过临时事务处理更大的数据量,您就会知道您的选择。还值得注意的是,单独的表变量事务不会被记录下来,并且无法回滚,而在临时表上完成的事务可以回滚!

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

最后,临时表会一直增加磁盘IO,因为他们总是使用tempdb而表变量可能不会增加它,这取决于内存的压力水平。

让我知道,如果你想知道如何调整你的tempdb,以获得更快的性能超过100%!

+0

克里斯,你为什么不建立一个SO账户? – 2009-09-09 15:44:33

2

有可能与MS SQL服务器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