基于SELECT TOP 1的UPDATE查询性能下降

时间:2018-05-29 15:01:06

标签: sql-server indexing query-performance

我正在尝试提高查询的性能,这需要花费很长时间才能运行,并且会理解我需要采取哪些不同的指针以使性能合理。 (索引和估计的执行计划信息包含在下面。)

正在更新的表table1有1000条记录,但被查询的表有1亿的范围。奇怪的是,我对最旧的值和最近的值使用几乎相同的查询,但最近值的查询在两秒内返回。这是对最旧值的查询;运行需要两分钟:

UPDATE table1
SET firstVal = (
                    SELECT TOP 1 val 
                    FROM table2 
                    WHERE table1.ID = ID
                    AND valID = 123
                    ORDER BY entryDate
                    )

查询最近的,在两秒钟内返回:

UPDATE table1
SET lastVal = (
                    SELECT TOP 1 val 
                    FROM table2  
                    WHERE table1.ID = ID
                    AND valID = 123
                    ORDER BY entryDate DESC
                    )

索引:

CREATE NONCLUSTERED INDEX [table2_IX9] ON [dbo].[table2]
(
    [valID] ASC,
    [entryDate] ASC,
    [ID] ASC
)
INCLUDE (   [val]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [AB]
GO

Index Seek(NonClustered)成本:68%
最高成本:29%

这个查询可以用更好的方式进行优化吗?在索引方面我需要不同的东西吗?提前感谢任何指导!

2 个答案:

答案 0 :(得分:0)

这对评论来说太长了,但这可能会更快:

UPDATE T1
SET firstVal = T2.val
FROM Table1 T1
     --This might need to be an OUTER APPLY, but impossible to tell from your post
     CROSS APPLY (SELECT TOP 1 ca.val
                  FROM Table2 ca
                  WHERE ca.ID = T1.ID
                    AND ca.valID = 123
                  ORDER BY ca.entryDate) T2;

您拥有它的方式可能意味着查询是针对每一行单独运行的,而不是作为数据集运行。这种方式将强制查询作为数据集运行。

答案 1 :(得分:0)

我最终做了什么:

SELECT ID, val, entryDate
INTO #tmpT2
FROM table2 
WHERE ID IN (SELECT ID FROM table1)
AND valID = 123

然后通过微调,在原始查询中换出#tmpT2 for table2:

UPDATE table1
SET firstVal = (
                    SELECT TOP 1 val 
                    FROM #tmpT2 
                    WHERE table1.ID = ID
                    ORDER BY entryDate
                    )

为什么:刚刚意识到索引就像它应该看起来一样,而table1如此之小,我可以尝试简单地使用临时表并检索valID = 123的所有ID,val和entryDates临时表。此步骤花了一秒钟,并使用原始查询是瞬时的。感谢您抽出宝贵时间思考这个问题并提出想法!