【发布时间】:2018-07-14 03:16:43
【问题描述】:
我观察到,将数据插入内存优化表比在 5-SSD 条带集上对基于磁盘的表进行等效的并行插入要慢得多。
--DDL for Memory-Optimized Table
CREATE TABLE [MYSCHEMA].[WIDE_MEMORY_TABLE]
(
[TX_ID] BIGINT NOT NULL
, [COLUMN_01] [NVARCHAR](10) NOT NULL
, [COLUMN_02] [NVARCHAR] (10) NOT NULL
--etc., about 100 columns
--at least one index is required for Memory-Optimized Tables
, INDEX IX_WIDE_MEMORY_TABLE_ENTITY_ID HASH (TX_ID) WITH (BUCKET_COUNT=10000000)
)
WITH (MEMORY_OPTIMIZED=ON, DURABILITY=SCHEMA_ONLY)
--DDL for Disk-Based Table
CREATE TABLE [MYSCHEMA].[WIDE_DISK_TABLE]
(
[TX_ID] BIGINT NOT NULL
, [COLUMN_01] [NVARCHAR](10) NOT NULL
, [COLUMN_02] [NVARCHAR] (10) NOT NULL
--etc., about 100 columns
--No indexes
) ON [PRIMARY]
对于这个特定的测试,我将 10,000,000 行以 25,000 为一组批处理到该表中。对于内存优化表,该语句看起来像这样:
--Insert to Memory-Optimized Table
INSERT INTO
WIDE_MEMORY_TABLE
(
TX_ID
, COLUMN_01
, COLUMN_02
--etc., about 100 columns
)
SELECT
S.COLUMN_01
, S.COLUMN_02
--etc., about 100 columns
FROM
[MYSCHEMA].[SOURCE_TABLE] AS S WITH(TABLOCK)
WHERE
S.TX_ID >= 1
AND S.TX_ID < 25001
OPTION (MAXDOP 4)
此过程继续加载 10,000,000 行。每次迭代只检索接下来的 25,000 行。 SELECT 在 [MY_SCHEMA].[SOURCE_TABLE] 上的覆盖索引上执行查找。查询计划向 BIG_MEMORY_TABLE 显示序列化插入。每组 25,000 行大约需要 1400 毫秒。
如果我对托管在 5 个 SSD 条带上的基于磁盘的表执行此操作(每个磁盘 5,000 IOPS,200MB/秒的吞吐量),则插入进度会快得多,平均约为 700 毫秒。在基于磁盘的情况下,查询对 [MY_SCHEMA].[WIDE_DISK_TABLE] 执行并行插入。请注意 [MYSCHEMA].[WIDE_DISK_TABLE] 上的 TABLOCK 提示。
--Insert to Disk-Based Table
INSERT INTO
WIDE_DISK_TABLE WITH(TABLOCK)
(
TX_ID
, COLUMN_01
, COLUMN_02
--etc., about 100 columns
)
SELECT
S.COLUMN_01
, S.COLUMN_02
--etc., about 100 columns
FROM
[MYSCHEMA].[SOURCE_TABLE] AS S WITH(TABLOCK)
WHERE
S.TX_ID >= 1
AND S.TX_ID < 25001
OPTION (MAXDOP 4)
当然,基于磁盘的表没有索引,TABLOCK 提示支持并行插入,但我希望从 INSERT 到 RAM 的方式更多。
有什么想法吗?
谢谢!
这里是在 3 种模式下运行的 100 个批次的比较:基于磁盘,使用延迟索引创建,基于磁盘使用索引,以及使用索引优化内存(内存优化表至少需要一个索引)。
【问题讨论】:
-
为什么不使用基于磁盘的索引进行测试?很容易认为这是很小的,但通常不是……工作量加倍有时是工作量的两倍。
-
您的内存表是否使用行溢出存储?想知道是否会导致性能下降。
-
这里的这一段看起来很相关aboutsqlserver.com/2016/09/27/…对于他们所做的具体实验“我的环境中INSERT语句的执行时间分别为153和7,722毫秒。使用行外存储,内存中OLTP需要向其他 20 个内部表添加数据,这比行内存储慢 40 倍。”
-
@MartinSmith 想法不错,但我们没有使用行外存储。它只是一堆 NVARCHAR (大部分是小的)和一些 DECIMAL。这是该表的 sys.dm_db_xtp_memory_consumers 输出的图像:imgur.com/a/Z99zy
-
@MartinSmith 这归结为并行的力量。查看我自己发布的答案和 Niko Neugebauer 的相关文章。
标签: sql-server performance query-performance memory-optimized-tables