OPENJSON使用CROSS / OUTER APPLY和数百万行表现不佳

时间:2017-03-13 18:38:29

标签: json sql-server-2016

我有一个包含数百万行和三个相关列的表:

WITH selected as (
    SELECT cycle_completa.numcycle AS actual_cycle, 
        min(cycle_completa.pump1pre) AS min_pump1pre, 
        min(cycle_completa.pump2pre) AS min_pump2pre, 
        min(cycle_completa.pump3pre) AS min_pump3pre, 
        min(cycle_completa.slidevel) AS min_slidevel, 
        min(cycle_completa.slidepos) AS min_slidepos, 
        min(cycle_completa.slideforce) AS min_slideforce, 
        min(cycle_completa.slideservopilotpre) AS min_slideservopilotpre, 
        min(cycle_completa.slidecentralpre) AS min_slidecentralpre, 
        min(cycle_completa.slidelateralpre) AS min_slidelateralpre, 
        min(cycle_completa.slideringpre) AS min_slideringpre, 
        min(cycle_completa.slidepistonpre) AS min_slidepistonpre, 
        min(cycle_completa.slidey42pre) AS min_slidey42pre, 
        min(cycle_completa.cushionforce) AS min_cushionforce, 
        min(cycle_completa.cushionservopilotpre) AS min_cushionservopilotpre,
        min(cycle_completa.cushionpistonpre) AS min_cushionpistonpre, 
        min(cycle_completa.cushionringpre) AS min_cushionringpre, 
        min(cycle_completa.pfillaccumpre) AS min_pfillaccumpre, 
        min(cycle_completa.pfillcentralpre) AS min_pfillcentralpre, 
        min(cycle_completa.pfilllateralpre) AS min_pfilllateralpre, 
        min(cycle_completa.pfillunlockingpre) AS min_pfillunlockingpre, 
        min(cycle_completa.reducedauxpumppre) AS min_reducedauxpumppre,
        min(cycle_completa.tankoiltemp) AS min_tankoiltemp
    FROM cycle_completa
    WHERE slidestage = 17
    GROUP BY cycle_completa.numcycle
)
UPDATE cycle_parametros cp
SET cp.seg3_min_valor_fmant_pump1pre = s.min_pump1pre,
    cp.seg3_min_valor_fmant_pump2pre = s.min_pump2pre,
    cp.seg3_min_valor_fmant_pump3pre = s.min_pump3pre,
    cp.seg3_min_valor_fmant_slidevel = s.min_slidevel,
    cp.seg3_min_valor_fmant_slidepos = s.min_slidepos,
    cp.seg3_min_valor_fmant_slideforce = s.min_slideforce,
    cp.seg3_min_valor_fmant_slideservopilotpre = s.min_slideservopilotpre,
    cp.seg3_min_valor_fmant_slidecentralpre = s.min_slidecentralpre,
    cp.seg3_min_valor_fmant_slidelateralpre = s.min_slidelateralpre,
    cp.seg3_min_valor_fmant_slideringpre = s.min_slideringpre,
    cp.seg3_min_valor_fmant_slidepistonpre = s.min_slidepistonpre,
    cp.seg3_min_valor_fmant_slidey42pre = s.min_slidey42pre,
    cp.seg3_min_valor_fmant_cushionforce = s.min_cushionforce,
    cp.seg3_min_valor_fmant_cushionservopilotpre = s.min_cushionservopilotpre,
    cp.seg3_min_valor_fmant_cushionpistonpre = s.min_cushionpistonpre,
    cp.seg3_min_valor_fmant_cushionringpre = s.min_cushionringpre,
    cp.seg3_min_valor_fmant_pfillaccumpre = s.min_pfillaccumpre,
    cp.seg3_min_valor_fmant_pfillcentralpre = s.min_pfillcentralpre,
    cp.seg3_min_valor_fmant_pfilllateralpre = s.min_pfilllateralpre,
    cp.seg3_min_valor_fmant_pfillunlockingpre = s.min_pfillunlockingpre,
    cp.seg3_min_valor_fmant_reducedauxpumppre = s.min_reducedauxpumppre,
    cp.seg3_min_valor_fmant_tankoiltemp = s.min_tankoiltemp
FROM selected AS s
WHERE cp.numcycle = s.actual_cycle

当我使用群集索引执行搜索时,它会按预期快速运行,例如:

CREATE TABLE [EventSourcing].[EventsTableCompressed](
    [DocumentKey] [nvarchar](200) NOT NULL,
    ...
    [JsonCompressed] [varbinary](max) NOT NULL,
    [JsonDecompressed]  AS (CONVERT([nvarchar](max),Decompress([JsonCompressed]))),
 CONSTRAINT [PK_EventsTableCompressed] PRIMARY KEY CLUSTERED 
(
    [DocumentKey] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

返回的行数量多于或少于100亿,IO为最小值(如预期的那样)

但是,如果我尝试使用CROSS APPLY OPENJSON或OUTER APPLY OPENJSON完成查询,则性能不佳(提取100行1分钟)

SELECT 
DocumentKey,
JSON_VALUE(JsonDecompressed, '$.MyJsonProperty') as MyJsonProperty
FROM  [EventSourcing].[EventsTableCompressed] C
where DocumentKey> 'RangeInit' and DocumentKey< 'RangeEnd'

检查查询计划,我在两种情况下都有相同的情况,大多数情况下使用集群索引查找。但是,在Profiler工具中,我可以在第二个查询中看到非常大的读取数和惊喜数。

我想知道这种行为的原因。似乎APPLY正在所有行上执行,而不仅仅是由where clausure过滤的行。是吗?

1 个答案:

答案 0 :(得分:1)

禁用数据库中的stadistic可防止出错。似乎第一次,必须更新统计数据或类似的东西(这就是大量或写入的原因)。