As tabelas com otimização de memória armazenam tipos de LOB em tabelas internas.
Eu tenho uma tabela sem tipos LOB explícitos, mas quando executo uma consulta em sys.memory_optimized_tables_internal_attributes , vejo colunas varchar(255) listadas com um valor type_desc de INTERNAL OFF-ROW DATA TABLE
.
SET ANSI_NULLS ON;
GO
SET QUOTED_IDENTIFIER ON;
GO
SET ANSI_PADDING ON;
GO
CREATE TABLE dbo.DERP
(
RECORD_KEY numeric(30, 0) NOT NULL
, COL_1 bigint NOT NULL
, COL_2 datetime2(0) NOT NULL
, COL_3 datetime2(0) NOT NULL
, COL_4 varchar(20) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
, COL_5 varchar(255) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
, COL_6 varchar(255) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
, COL_7 date NULL
, COL_8 bigint NULL
, COL_9 char(1) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
, COL_10 int NULL
, COL_11 varchar(255) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
, COL_12 int NULL
, COL_13 char(1) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
, COL_14 char(1) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
, COL_15 varchar(255) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
, COL_16 varchar(255) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
, COL_17 varchar(255) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
, COL_18 varchar(255) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
, COL_19 varchar(255) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
, COL_20 char(3) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
, COL_21 bigint NULL
, COL_22 bigint NULL
, COL_23 varchar(255) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
, COL_24 varchar(255) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
, COL_25 int NULL
, COL_26 varchar(255) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
, COL_27 varchar(255) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
, COL_28 varchar(255) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
, COL_29 varchar(255) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
, COL_30 decimal(7, 4) NULL
, COL_31 varchar(255) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
, COL_32 decimal(8, 4) NULL
, COL_33 varchar(255) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
, COL_34 varchar(255) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
, COL_35 char(1) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
, COL_36 varchar(255) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
, COL_37 int NULL
, COL_38 varchar(255) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
, COL_39 varchar(255) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
, COL_40 char(1) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
, COL_41 int NULL
, COL_42 varchar(255) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
, COL_43 varchar(255) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
, COL_44 varchar(255) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
, COL_45 int NULL
, COL_46 varchar(255) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
, COL_47 char(1) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
, COL_48 varchar(255) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
, COL_49 int NULL
, COL_50 varchar(255) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
, COL_51 int NULL
, COL_52 varchar(255) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
, COL_53 char(1) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
, COL_54 varchar(255) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
, COL_55 varchar(255) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
, COL_56 char(1) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
, COL_57 varchar(255) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
, COL_58 varchar(255) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
, COL_59 char(1) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
, COL_60 char(1) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
, COL_61 date NULL
, COL_62 char(2) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
, COL_63 int NULL
, COL_64 varchar(255) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
, COL_65 varchar(255) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
, COL_66 int NULL
, COL_67 varchar(255) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
, COL_68 int NULL
, COL_69 char(1) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
, COL_70 varchar(255) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
, COL_71 char(1) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
, COL_72 varchar(255) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
, COL_73 varchar(255) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
, COL_74 char(3) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
, COL_75 varchar(255) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
, COL_76 varchar(255) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
, COL_77 char(3) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
, COL_78 char(2) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
, COL_79 varchar(255) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
, COL_80 bigint NULL
, CONSTRAINT dbo_DERP
PRIMARY KEY NONCLUSTERED
(
RECORD_KEY ASC
)
)
WITH (MEMORY_OPTIMIZED = ON, DURABILITY = SCHEMA_AND_DATA);
GO
SET ANSI_PADDING OFF;
GO
A execução da consulta a seguir gera 10 colunas (COL_58, COL_64, COL_65, COL_67, COL_70, COL_72, COL_73, COL_75, COL_76, COL_79) listadas como tabela de dados fora da linha
SELECT
QUOTENAME(SCHEMA_NAME(o.schema_id)) + N'.' + QUOTENAME(OBJECT_NAME(moa.object_id)) AS 'table'
, c.name AS 'column'
, c.max_length
, moa.type_desc
FROM
sys.memory_optimized_tables_internal_attributes moa
INNER JOIN
sys.columns c
ON moa.object_id = c.object_id
AND moa.minor_id = c.column_id
INNER JOIN
sys.objects o
ON moa.object_id = o.object_id
WHERE
o.name = 'DERP'
ORDER BY
1;
Presumo que essa decisão de armazenamento seja baseada no fato de essa tabela ser super ampla (quase 10.400 bytes de largura), sim?
SQL Server 2016 SP1, CU2, também conhecido como 13.0.4422.0
Bill você está absolutamente correto e este é um novo recurso adicionado no SQL 2016.
Tamanho de tabela e linha em tabelas com otimização de memória
Para provar que tirei 10 de vocês colunas de tipo de dados varchar(255) e recriei a tabela. Agora recebo zero registro para a 2ª consulta. Porque o comprimento máximo da linha se torna 7824 MB.
Agora, se você adicionar mais uma coluna com varchar(255), verá uma única entrada para a tabela de dados fora da linha interna porque o comprimento máximo da linha é superior a 8060 MB (8079 MB)
Você pode usar essa consulta para verificar o comprimento máximo da linha.