Questo è il secondo articolo di una serie di articoli sull'OLTP in memoria di SQL Server.
L'articolo introduttivo — SQL Server In-Memory OLTP, ha introdotto brevemente le nozioni di base del nuovo motore Hekaton. In questa parte ci concentreremo sulla pratica. Per essere più specifici, vedremo come creare database e tabelle ottimizzati in memoria e anche come valutarli con l'aiuto di T-SQL.
Prerequisiti per iniziare a utilizzare database ottimizzati per la memoria
L'OLTP in memoria viene installato automaticamente con un'edizione Enterprise o Developer a 64 bit di SQL Server 2014 o SQL Server 2016. L'edizione a 32 bit di SQL Server non fornisce componenti OLTP in memoria.
Pertanto, se sul computer è installata l'edizione Developer di SQL Server a 64 bit, è possibile iniziare a creare database e strutture di dati che memorizzeranno dati ottimizzati per la memoria senza alcuna configurazione aggiuntiva.
Ogni singolo database che conterrà tabelle con ottimizzazione per la memoria dovrebbe contenere un filegroup MEMORY_OPTIMIZED_DATA. Questo filegroup contiene uno o più contenitori. Ogni singolo contenitore memorizza dati e/o file delta. SQL Server utilizza questi file per ripristinare le tabelle ottimizzate per la memoria. I contenitori possono essere posizionati su diversi array di dischi,
in modo simile ai filegroup FILESTREAM.
La sintassi per la creazione di filegroup con ottimizzazione per la memoria è quasi la stessa di un filegroup FILESTREAM tradizionale, con le diverse differenze:
- È possibile creare un solo filegroup ottimizzato per la memoria per un database.
- L'opzione CONTAINS MEMORY_OPTIMIZED_DATA deve essere specificata in modo esplicito.
Puoi creare il filegroup nel processo di creazione di un database:
CREATE DATABASE InMemoryDemo ON PRIMARY ( NAME = N'InMemoryDemo', FILENAME = N'D:\Data\InMemoryOLTPDemo.mdf' ), FILEGROUP IMOFG CONTAINS MEMORY_OPTIMIZED_DATA ( NAME = N'InMemoryDemo_Data', FILENAME = N'D:\IMOFG\InMemoryDemo_Data.mdf' )
In alternativa, puoi aggiungere il filegroup MEMORY_OPTIMIZED_DATA a un database esistente, quindi aggiungere i file a quel filegroup.
-- Adding the containers ALTER DATABASE DemoDB ADD FILE ( NAME = 'DemoDB_Mod', FILENAME = 'D:\Data\DemoDB_Mod' ) TO FILEGROUP DemoDB_Mod
Internamente, In-Memory OLTP utilizza un meccanismo di streaming basato sulla tecnologia FILESTREAM, che è ben adattato per l'accesso I/O sequenziale.
Creazione di tabelle ottimizzate per la memoria
Ora abbiamo tutto ciò di cui abbiamo bisogno per iniziare a creare oggetti con ottimizzazione per la memoria. Creiamo una tabella con ottimizzazione per la memoria.
La sintassi per la creazione di tabelle ottimizzate per la memoria è molto simile a quella per la creazione di tabelle basate su disco. Tuttavia, ci sono alcune estensioni e restrizioni:
- La clausola MEMORY_OPTIMIZED =ON identifica una tabella come ottimizzata in memoria.
- Le tabelle ottimizzate per la memoria non supportano tutti i tipi di dati supportati dalle tabelle tradizionali. I seguenti tipi di dati non sono supportati:
- datatimeoffset
- geografia
- geometria
- gerarchia
- versione riga
- XML
- variante_sql
- Tipi definiti dall'utente
È possibile creare una tabella ottimizzata per la memoria con i seguenti valori di durabilità:SCHEMA_AND_DATA o SCHEMA_ONLY. SCHEMA_AND_DATA è il valore predefinito.
Se specifichi SCHEMA_ONLY, tutte le modifiche alla tabella non verranno registrate e i dati della tabella non verranno archiviati sul disco.
Ogni singola tabella ottimizzata per la memoria deve contenere almeno un indice. Si noti che il vincolo PRIMARY KEY crea implicitamente un indice. Una tabella durevole ottimizzata per la memoria richiede sempre un vincolo PRIMARY KEY.
CREATE TABLE dbo.Person ( [Name] VARCHAR(32) NOT NULL PRIMARY KEY NONCLUSTERED ,[City] VARCHAR(32) NULL ,[Country] VARCHAR(32) NULL ,[State_Province] VARCHAR(32) NULL ,[LastModified] DATETIME NOT NULL ) WITH (MEMORY_OPTIMIZED = ON, DURABILITY = SCHEMA_AND_DATA);
È possibile aggiungere indici compositi dopo aver creato tutte le colonne:
CREATE TABLE dbo.Person ( [Name] VARCHAR(32) NOT NULL PRIMARY KEY NONCLUSTERED ,[City] VARCHAR(32) NULL ,[Country] VARCHAR(32) NULL ,[State_Province] VARCHAR(32) NULL ,[LastModified] DATETIME NOT NULL ,INDEX T1_INDX_C1C2 NONCLUSTERED ([Name], [City]) ) WITH (MEMORY_OPTIMIZED = ON, DURABILITY = SCHEMA_AND_DATA);
Quando crei la tabella ottimizzata in memoria, il motore OLTP in memoria crea routine DML per poter accedere a tale tabella. Carica le routine come file DLL. Per un'operazione specifica, SQL Server chiama un file DLL richiesto.
Alterare tabelle e indici
Era impossibile ALTERARE le tabelle prima di SQL Server 2016. Per apportare modifiche allo schema, dovevi eliminare e ricreare la tabella in memoria.
Nella nuova versione di SQL Server, ALTER TABLE è parzialmente supportato.
SQL Server 2016 offre la possibilità di eseguire operazioni offline:aggiunta e eliminazione (modifica) di colonne, indici e vincoli. Inoltre, ora è possibile lavorare con le tabelle in memoria utilizzando il designer di tabelle SSMS o l'editor di tabelle dbForge Studio per SQL Server.
Si noti che ALTER TABLE richiede la ricostruzione della tabella. Ecco perché è necessario essere sicuri di disporre di memoria sufficiente prima di eseguire questa operazione. Durante l'operazione di ricostruzione, ogni singola riga viene reinserita nella nuova tabella e la tabella non è disponibile mentre viene eseguita l'operazione ALTER.
È possibile apportare più modifiche a una singola tabella e combinarle in un'unica istruzione ALTER TABLE. Puoi AGGIUNGERE colonne, indici e vincoli ed eliminare colonne, indici e vincoli. Nota che non puoi combinare i comandi ADD e DROP insieme in un'unica ALTER TABLE.
-- index operations -- change hash index bucket count ALTER TABLE dbo.TableName ALTER INDEX IX_Name REBUILD WITH (BUCKET_COUNT = 131072); GO -- add index ALTER TABLE dbo.TableName ADD INDEX IX_Name NONCLUSTERED (ColName); GO -- drop index ALTER TABLE dbo.TableName DROP INDEX IX_Name; GO -- add multiple indexes ALTER TABLE dbo.TableName ADD INDEX IX_Name NONCLUSTERED (ColName), INDEX IX_Name2 NONCLUSTERED (ColName2); GO -- Add a new column and an index ALTER TABLE dbo.TableName ADD Date DATETIME, INDEX IX_Name NONCLUSTERED (ColName); GO -- Drop a column ALTER TABLE dbo.TableName DROP COLUMN ColName; GO
Tipi di tabella e variabili di tabella
SQL Server 2016 ti offre la possibilità di creare tipi di tabella ottimizzati per la memoria che puoi utilizzare durante la definizione di una variabile di tabella:
CREATE TYPE TypeName AS TABLE ( Col1 SMALLINT NOT NULL, Col2 INT NOT NULL, Col3 INT NOT NULL, Col4 INT NOT NULL, INDEX IX_Col1 NONCLUSTERED HASH (Col1) WITH (BUCKET_COUNT = 131072), INDEX IX_Col1 NONCLUSTERED (Col2)) WITH (MEMORY_OPTIMIZED = ON); GO DECLARE @VariableName TypeName; GO
Questa variabile è salvata solo in memoria. Le tabelle e i tipi di tabella ottimizzati in memoria utilizzano le stesse strutture di dati, quindi l'accesso ai dati sarà più efficiente rispetto alle variabili di tabella basate su disco.
Per ulteriori dettagli, fare riferimento al seguente post del blog MSDN:Miglioramento delle prestazioni di tabelle temporanee e variabili di tabella mediante l'ottimizzazione della memoria
Riepilogo
L'OLTP in memoria è una tecnologia relativamente giovane progettata per funzionare con sistemi OLTP enormi e molto occupati che supportano centinaia o addirittura migliaia di utenti simultanei. È stata introdotta in SQL Server 2014 e si è evoluta in SQL Server 2016.
Allo stesso tempo, la tecnologia contiene una serie di restrizioni e limitazioni.
Non tutte le funzionalità e i tipi di dati di T-SQL sono supportati dalla memoria- tabelle ottimizzate, tali tabelle non possono contenere righe che superano 8060 byte e inoltre non supportano
ROW-OVERFLOW e l'archiviazione LOB. Non è possibile modificare tabelle e indici (in SQL Server 2014), una volta creata la tabella.
Nonostante ciò, prevediamo che ulteriori versioni di In-Memory OLTP avranno meno limitazioni!
Leggi anche:
Utilizzo degli indici nelle tabelle con ottimizzazione per la memoria di SQL Server