Sdílet prostřednictvím


Aplikační vzor pro rozdělení paměťově optimalizovaných tabulek

platí pro: SQL Server Azure SQL DatabaseAzure SQL Managed Instance

In-Memory OLTP podporuje vzor návrhu aplikace, který velkoryse využívá výkonové prostředky pro relativně aktuální data. Tento model se může použít, když se aktuální data čtou nebo aktualizují mnohem častěji než starší data. V tomto případě říkáme, že aktuální data jsou aktivní nebo horká a starší data jsou studená.

Hlavní myšlenkou je ukládat horká data v tabulce optimalizované pro paměť. Na týdenní nebo měsíční bázi se starší data, která se stala neaktivní, přesunou do dělené tabulky. Dělená tabulka obsahuje data uložená na disku nebo na jiném pevném disku, ne v paměti.

Tento návrh obvykle používá klíč datum a čas, který umožňuje procesu přesunu efektivně rozlišit mezi teplými a chladnými daty.

Pokročilé rozdělení

Návrh má v úmyslu napodobovat dělenou tabulku, která má také jeden oddíl optimalizovaný pro paměť. Aby tento návrh fungoval, musíte zajistit, aby všechny tabulky sdílely společné schéma. Ukázka kódu dále v tomto článku ukazuje techniku.

Podle definice se předpokládá, že nová data jsou horká. Aktivní data jsou vkládána a aktualizována v paměťově optimalizované tabulce. Studená data se udržují v tradiční dělené tabulce. Uložená procedura pravidelně přidává nový oddíl. Oddíl obsahuje nejnovější studená data, která byla přesunuta z paměťově optimalizované tabulky.

Pokud operace potřebuje jen horká data, může pro přístup k datům použít nativně zkompilované uložené procedury. Operace, které můžou přistupovat k horkým nebo studeným datům, musí použít interpretovanou transact-SQL, aby bylo možné spojit tabulku optimalizovanou pro paměť s dělenou tabulkou.

Přidejte oddíl

Data, která se nedávno ochladila, se musí přesunout do dělené tabulky. Postup pro tuto pravidelnou výměnu oddílů je následující:

  1. U dat v tabulce optimalizované pro paměť určete datum a čas, která je mezí mezi horkými a nově zchlazenými daty.
  2. Vložte nově studená data z tabulky In-Memory OLTP do tabulky cold_staging .
  3. Odstraňte stejná studená data z tabulky optimalizované pro paměť.
  4. Zaměňte tabulku cold_staging za oddíl.
  5. Přidejte oddíl.

Časové období údržby

Jedním z předchozích kroků je odstranění nově ochlazených dat z pamětí optimalizované tabulky. Mezi odstraněním a posledním krokem, který přidá nový oddíl, je časový interval. Během tohoto intervalu selže jakákoli aplikace, která se pokusí přečíst nově studená data.

Související ukázku najdete v Application-Level Particionování.

Ukázka kódu

Následující Transact-SQL ukázka se zobrazí v řadě menších bloků kódu, pouze pro usnadnění prezentace. Všechny je můžete připojit do jednoho velkého bloku kódu pro testování.

Jako celek ukázka T-SQL ukazuje, jak používat tabulku optimalizovanou pro paměť s dělenou tabulkou založenou na disku.

První fáze ukázky T-SQL vytvoří databázi a pak vytvoří objekty, jako jsou tabulky v databázi. Pozdější fáze ukazují, jak přesunout data z tabulky optimalizované pro paměť do dělené tabulky.

Vytvoření databáze

Tato část ukázky T-SQL vytvoří testovací databázi. Databáze je nakonfigurovaná tak, aby podporovala tabulky optimalizované pro paměť i dělené tabulky.

CREATE DATABASE PartitionSample;
GO

-- Add a FileGroup, enabled for In-Memory OLTP.
-- Change file path as needed.

ALTER DATABASE PartitionSample
    ADD FILEGROUP PartitionSample_mod
    CONTAINS MEMORY_OPTIMIZED_DATA;

ALTER DATABASE PartitionSample
    ADD FILE(
        NAME = 'PartitionSample_mod',
        FILENAME = 'c:\data\PartitionSample_mod')
    TO FILEGROUP PartitionSample_mod;
GO

Vytvoření tabulky optimalizované pro paměť pro horká data

Tato část vytvoří tabulku optimalizovanou pro paměť, která obsahuje nejnovější data, což jsou většinou stále horká data.

USE PartitionSample;
GO

-- Create a memory-optimized table for the HOT Sales Order data.
-- Notice the index that uses datetime2.

CREATE TABLE dbo.SalesOrders_hot (
   so_id INT IDENTITY PRIMARY KEY NONCLUSTERED,
   cust_id INT NOT NULL,
   so_date DATETIME2 NOT NULL INDEX ix_date NONCLUSTERED,
   so_total MONEY NOT NULL,
   INDEX ix_date_total NONCLUSTERED (so_date desc, so_total desc)
) WITH (MEMORY_OPTIMIZED=ON);
GO

Vytvořte rozdělenou tabulku pro studená data

Tato část vytvoří dělenou tabulku, která obsahuje studená data.

-- Create a partition and table for the COLD Sales Order data.
-- Notice the index that uses datetime2.

CREATE PARTITION FUNCTION [ByDatePF](datetime2) AS RANGE RIGHT
   FOR VALUES();
GO

CREATE PARTITION SCHEME [ByDateRange]
   AS PARTITION [ByDatePF]
   ALL TO ([PRIMARY]);
GO

CREATE TABLE dbo.SalesOrders_cold (
   so_id INT NOT NULL,
   cust_id INT NOT NULL,
   so_date DATETIME2 NOT NULL,
   so_total MONEY NOT NULL,
   CONSTRAINT PK_SalesOrders_cold PRIMARY KEY (so_id, so_date),
   INDEX ix_date_total NONCLUSTERED (so_date desc, so_total desc)
) ON [ByDateRange](so_date);
GO

Vytvoření tabulky pro ukládání studených dat během přesunu

Tento úsek vytvoří tabulku cold_staging. Vytvoří se také zobrazení, které sjednocuje horká a studená data ze dvou tabulek.

-- A table used to briefly stage the newly cold data, during moves to a partition.

CREATE TABLE dbo.SalesOrders_cold_staging (
   so_id INT NOT NULL,
   cust_id INT NOT NULL,
   so_date datetime2 NOT NULL,
   so_total MONEY NOT NULL,
   CONSTRAINT PK_SalesOrders_cold_staging PRIMARY KEY (so_id, so_date),
   INDEX ix_date_total NONCLUSTERED (so_date desc, so_total desc),
   CONSTRAINT CHK_SalesOrders_cold_staging CHECK (so_date >= '1900-01-01')
);
GO

-- A view, for retrieving the aggregation of hot plus cold data.

CREATE VIEW dbo.SalesOrders
AS SELECT so_id,
          cust_id,
          so_date,
          so_total,
          1 AS 'is_hot'
       FROM dbo.SalesOrders_hot
   UNION ALL
   SELECT so_id,
          cust_id,
          so_date,
          so_total,
          0 AS 'is_cold'
       FROM dbo.SalesOrders_cold;
GO

Vytvoření uložené procedury

Tato část vytvoří uloženou proceduru, kterou pravidelně spouštíte. Tento postup přesune nově studená data z tabulky optimalizované pro paměť do dělené tabulky.

-- A stored procedure to move all newly cold sales orders data
-- to its staging location.

CREATE PROCEDURE dbo.usp_SalesOrdersOffloadToCold @splitdate datetime2
   AS
   BEGIN
      BEGIN TRANSACTION;

      -- Insert the cold data as a temporary heap.
      INSERT INTO dbo.SalesOrders_cold_staging WITH (TABLOCKX)
      SELECT so_id , cust_id , so_date , so_total
         FROM dbo.SalesOrders_hot WITH (serializable)
         WHERE so_date <= @splitdate;

      -- Delete the moved data from the hot table.
      DELETE FROM dbo.SalesOrders_hot WITH (SERIALIZABLE)
         WHERE so_date <= @splitdate;

      -- Update the partition function, and switch in the new partition.
      ALTER PARTITION SCHEME [ByDateRange] NEXT USED [PRIMARY];

      DECLARE @p INT = (
        SELECT MAX(partition_number)
            FROM sys.partitions
            WHERE object_id = OBJECT_ID('dbo.SalesOrders_cold'));

      EXEC sp_executesql
        N'ALTER TABLE dbo.SalesOrders_cold_staging
            SWITCH TO dbo.SalesOrders_cold partition @i',
        N'@i int',
        @i = @p;

      ALTER PARTITION FUNCTION [ByDatePF]()
      SPLIT RANGE( @splitdate);

      -- Modify a constraint on the cold_staging table, to align with new partition.
      ALTER TABLE dbo.SalesOrders_cold_staging
         DROP CONSTRAINT CHK_SalesOrders_cold_staging;

      DECLARE @s nvarchar( 100) = CONVERT( nvarchar( 100) , @splitdate , 121);
      DECLARE @sql nvarchar( 1000) = N'alter table dbo.SalesOrders_cold_staging 
         add constraint CHK_SalesOrders_cold_staging check (so_date > ''' + @s + ''')';
      PRINT @sql;
      EXEC sp_executesql @sql;

      COMMIT;
END;
GO

Příprava ukázkových dat a ukázka uložené procedury

Tato část vygeneruje a vloží ukázková data a pak spustí uloženou proceduru jako ukázku.

-- Insert sample values into the hot table.
INSERT INTO dbo.SalesOrders_hot VALUES(1,SYSDATETIME(), 1);
GO
INSERT INTO dbo.SalesOrders_hot VALUES(1, SYSDATETIME(), 1);
GO
INSERT INTO dbo.SalesOrders_hot VALUES(1, SYSDATETIME(), 1);
GO

-- Verify that the hot data is in the table, by selecting from the view.
SELECT * FROM dbo.SalesOrders;
GO

-- Treat all data in the hot table as cold data:
-- Run the stored procedure, to move (offload) all sales orders to date to cold storage.
DECLARE @t datetime2 = SYSDATETIME();
EXEC dbo.usp_SalesOrdersOffloadToCold @t;

-- Again, read hot plus cold data from the view.
SELECT * FROM dbo.SalesOrders;
GO

-- Retrieve the name of every partition.
SELECT OBJECT_NAME( object_id) , * FROM sys.dm_db_partition_stats ps
   WHERE object_id = OBJECT_ID( 'dbo.SalesOrders_cold');

-- Insert more data into the hot table.
INSERT INTO dbo.SalesOrders_hot VALUES(2, SYSDATETIME(), 1);
GO
INSERT INTO dbo.SalesOrders_hot VALUES(2, SYSDATETIME(), 1);
GO
INSERT INTO dbo.SalesOrders_hot VALUES(2, SYSDATETIME(), 1);
GO

-- Read hot plus cold data from the view.
SELECT * FROM dbo.SalesOrders;
GO

-- Again, run the stored procedure, to move all sales orders to date to cold storage.
DECLARE @t datetime2 = SYSDATETIME();
EXEC dbo.usp_SalesOrdersOffloadToCold @t;

-- Read hot plus cold data from the view.
SELECT * FROM dbo.SalesOrders;
GO

-- Again, retrieve the name of every partition.
-- The stored procedure can modify the partitions.
SELECT OBJECT_NAME( object_id) , partition_number , row_count
  FROM sys.dm_db_partition_stats ps
  WHERE object_id = OBJECT_ID( 'dbo.SalesOrders_cold')
    AND index_id = 1;

Zahoďte všechny ukázkové objekty.

Nezapomeňte vyčistit ukázkovou testovací databázi z vašeho testovacího systému.

-- You must first leave the context of the PartitionSample database.

-- USE <A-Database-Name-Here>;
GO

DROP DATABASE PartitionSample;
GO

Viz také

tabulkyMemory-Optimized