内存表中的查询比基于磁盘的查询要慢

时间:2017-07-07 08:15:33

标签: sql-server performance memory-optimized-tables

我正在使用已经构建的表,我必须将其迁移到内存优化的表。以下是基于磁盘的克隆。两者都具有相同的结构,但基于磁盘的表没有主键,即使OID字段不应重复。

CREATE TABLE [dbo].[DATA_IM](
    [OID]       [varchar](36) NOT NULL, -- NEWID()
    [YEAR]      [varchar](15) NOT NULL  INDEX hash_sce HASH (YEAR) WITH (BUCKET_COUNT = 128),
    [MONTH]     [varchar](2)  NOT NULL,
    [DEPARTMENT][varchar](30) NOT NULL  INDEX hash_dep  HASH (DEPARTMENT)  WITH (BUCKET_COUNT = 64),
    [ACCOUNT]   [varchar](30) NOT NULL  INDEX hash_acct HASH (ACCOUNT)     WITH (BUCKET_COUNT = 2048),
    [DIM1]      [varchar](30) NULL      INDEX hash_de1  HASH (DIM1) WITH (BUCKET_COUNT = 256),
    [DIM2]      [varchar](30) NULL      INDEX hash_de2  HASH (DIM2) WITH (BUCKET_COUNT = 256),
    [DIM3]      [varchar](30) NULL      INDEX hash_de3  HASH (DIM3) WITH (BUCKET_COUNT = 256),
    [DIM4]      [varchar](30) NULL      INDEX hash_de4  HASH (DIM4) WITH (BUCKET_COUNT = 256),
    [DIM5]      [varchar](30) NULL,
    [CATEGORY]  [varchar](30) NOT NULL INDEX hash_cat HASH (CATEGORY) WITH (BUCKET_COUNT = 256),
    [VALUE]     [numeric](27, 9) NOT NULL,
    [CURRENCY]  [varchar](5)     NULL,
    [ORIGIN]    [varchar](80)   NULL,
    [USERUPD]   [varchar](255)  NULL,
    [DATEUPD]   [datetime]      NULL,
    [NOTE]      [varchar](1000) NULL
)
WITH (MEMORY_OPTIMIZED = ON, DURABILITY = SCHEMA_ONLY)

由于每个内存优化表必须至少有一个索引,而列是其他表的外键,我已经使这些列哈希索引计算了BUCKET_COUNT,如网上所示:

with cte1 AS (select count(distinct year)        year from data),
     cte2 AS (select count(distinct department)  dept from data)

SELECT  POWER(2, CEILING(LOG(year) / LOG(2))) AS [year],
        POWER(2, CEILING(LOG(dept) / LOG(2))) AS [dept]

FROM cte1, cte2

然而,诸如带有/ out group by的简单选择之类的查询比对原始表执行的查询要慢。我也尝试过使用非聚簇索引并增加桶数,但仍然相同。

我怎样才能加快查询速度?

1 个答案:

答案 0 :(得分:0)

您应该添加

OPTION (RECOMPILE)

在声明的末尾:

with cte1 AS (select count(distinct year)        year from data),
     cte2 AS (select count(distinct department)  dept from data)

SELECT  POWER(2, CEILING(LOG(year) / LOG(2))) AS [year],
        POWER(2, CEILING(LOG(dept) / LOG(2))) AS [dept]

FROM cte1, cte2
OPTION (RECOMPILE)

SQL Server并没有真正为此优化,因为它在创建变量表(无记录)时会编译其计划。当您用数据填充数据时,由于在第一次编译时就没有数据,因此未优化已编译的计划。

添加此选项后,它会告诉SQL Server重新编译,请记住现在有数据。

应该更快一些。