2008-08-26 10 views
16

Récemment, j'ai commencé à modifier certaines de nos applications afin de prendre en charge MS SQL Server en tant que solution alternative. L'un des problèmes de compatibilité que j'ai rencontré est l'utilisation de CREATE TEMPORARY TABLE de MySQL pour créer des tables en mémoire qui contiennent des données pour un accès très rapide pendant une session sans besoin de stockage permanent.MS-SQL prend-il en charge les tables en mémoire?

Quel est l'équivalent en MS SQL?

Une exigence est que je dois être en mesure d'utiliser la table temporaire comme les autres, en particulier JOIN avec les permanents.

+1

J'espère que vous êtes au courant que dans MySQL, les tables temporaires créées par les utilisateurs ne sont pas en mémoire par défaut! Seulement si vous spécifiez ENGINE = MEMORY dans l'instruction CREATE TABLE, la table sera en mémoire. Sinon, la table temporaire sera créée avec le moteur de stockage par défaut, probablement MyISAM ou INNODB, et sauvegardée sur le disque. Ne confondez pas les tables créées par l'utilisateur avec des tables temporaires internes créées par MySQL lors de jointures complexes. Ceux-ci sont créés en mémoire, si possible. –

Répondre

13

@Keith

C'est une idée fausse: Les variables de table ne sont pas nécessairement stockés dans la mémoire. En fait, SQL Server décide de conserver la variable en mémoire ou de la renvoyer à TempDB. Il n'existe aucun moyen fiable (au moins dans SQL Server 2005) pour garantir que les données de table sont conservées en mémoire. Pour plus d'informations détaillées, regardez here

0

CREATE TABLE #tmptablename

Utilisez le préfixe signe dièse/livre

3

Vous pouvez déclarer une "variable de table" dans SQL Server 2005, comme ceci:

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

Vous faites référence alors il a juste comme une variable:

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

Pas besoin de le laisser tomber - il part quand La variable sort du champ d'application.

0

La syntaxe que vous voulez est:

create table #tablename

Le préfixe # identifie la table comme une table temporaire.

1

Un bon blog post here mais fondamentalement préfixe des tables temporaires locales aveC# et la température globale aveC## - par exemple

CREATE TABLE #localtemp 
17

Vous pouvez créer des variables de table (en mémoire), et deux types différents de table temporaire:

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

Suite à des commentaires, je pense que cela a besoin d'un peu de clarification.

#table et ##table sera toujours dans TempDB.

@Table Les variables seront normalement en mémoire, mais ne sont pas garanties. SQL décide en fonction du plan de requête et utilise TempDB s'il en a besoin.

1

Je comprends ce que vous essayez d'atteindre. Bienvenue dans le monde d'une variété de bases de données!SQL Server 2000 prend en charge les tables temporaires créées en préfixant un # au nom de la table, ce qui en fait une table temporaire accessible localement (locale à la session) et précédant ## au nom de la table, pour des tables temporaires globalement accessibles, par exemple #MyLocalTable et ## MyGlobalTable respectivement.

SQL Server 2005 et versions ultérieures prennent en charge les tables temporaires (locales, globales) et les variables de table - attention aux nouvelles fonctionnalités sur les variables de table dans SQL 2008 et version 2! La différence entre les tables temporaires et les variables de table n'est pas si grande mais réside dans la manière dont le serveur de base de données les gère.

Je ne voudrais pas parler d'anciennes versions de SQL Server comme 7, 6, bien que je travaille avec eux et il est d'où je viens quand même :-)

Il est courant de penser que les variables de table résident toujours en mémoire mais c'est faux. Selon l'utilisation de la mémoire et le volume de transactions du serveur de base de données, les pages d'une variable de table peuvent être exportées de la mémoire et écrites dans tempdb et le reste du traitement y est effectué (dans tempdb). S'il vous plaît noter que tempdb est une base de données sur une instance sans objets permanents dans la nature mais il est responsable de la gestion des charges de travail impliquant des transactions secondaires comme le tri, et d'autres travaux de traitement qui est de nature temporaire. D'autre part, les variables de table (généralement avec des données plus petites) sont stockées en mémoire (RAM) ce qui les rend plus rapides à accéder et donc moins d'E/S sur le disque tempdb. connectez-vous à tempdb.

Les variables de table ne peuvent pas être indexées tandis que les tables temporaires (locales et globales) peuvent être indexées pour un traitement plus rapide dans le cas où la quantité de données est importante. Vous connaissez donc votre choix en cas de traitement plus rapide avec des volumes de données plus importants par des transactions temporaires. Il convient également de noter que les transactions sur les variables de table ne sont pas enregistrées et ne peuvent pas être annulées, alors que celles effectuées sur les tables temporaires peuvent être annulées! En résumé, les variables de table sont meilleures pour les données plus petites, tandis que les tables temporaires sont préférables pour les données plus importantes traitées temporairement. Si vous souhaitez également un contrôle des transactions correct à l'aide de blocs de transaction, les variables de table ne sont pas une option pour annuler des transactions. Il est donc préférable d'utiliser des tables temporaires dans ce cas. Enfin, les tables temporaires augmenteront toujours l'E/S du disque car elles utilisent toujours tempdb alors que les variables de table ne peuvent pas l'augmenter, en fonction des niveaux de contrainte mémoire. Faites-moi savoir si vous souhaitez obtenir des conseils sur la façon de régler votre tempdb pour gagner beaucoup plus rapidement et dépasser 100%!

+0

Chris, pourquoi ne pas créer un compte SO? –

+0

@Chris - s'il vous plaît laissez les lignes tag religieuses à la fin de votre poste. Aussi les choses auto-promotionnelles appartiennent à votre profil, pas à la fin de votre message. – slugster

2

Il est possible avec MS SQL Server 2014.

Voir: http://msdn.microsoft.com/en-us/library/dn133079.aspx

Voici un exemple de code de génération 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 
Questions connexes