我有这样的SQL查询:
DECLARE @cdate1 date = '20200401 00:00:00'
DECLARE @cdate2 date = '20200630 23:59:59'
SELECT DISTINCT ([hf].[id])
FROM ((([hf]
JOIN [pw] AS [PP] ON [PP].[identity] = [hf].[id]
AND [PP].[type] = 67
AND [PP].[ideletestate] = 0
AND [PP].[datein] = (SELECT MAX([datein])
FROM [pw]
WHERE [pw].[identity] = [hf].[id]
AND [pw].[ideletestate] = 0
AND [pw].[type] = 67))
JOIN [px] ON [px].[idpaper] = [PP].[id]
AND [px].[ideletestate] = 0
AND [px].[type] = 30036
AND [px].[nazvanie] NOT LIKE '')
JOIN [pw] ON ([pw].[identity] = [hf].[id]
AND ([pw].[id] > 0)
AND ([pw].[ideletestate] = 0)
AND ([pw].[type] IN (16, 2, 3012, 19, 3013)))
LEFT JOIN [px] AS [px102] ON [px102].[idpaper] = [pw].[id]
AND [px102].[type] = 102
AND [px102].[ideletestate] = 0)
WHERE
(([pw].[idcompany] in (12461, 12466, 12467, 12462, 12463, 13258)) OR
([pw].[idcompany2] in (12461, 12466, 12467, 12462, 12463, 13258)) OR
([px102].[idcompany] in (12461, 12466, 12467, 12462, 12463, 13258)) ) AND
[pw].[datein] >= @cdate1 AND [pw].[datein] <= @cdate2它工作得很好,但如果我像这样打印...AND [pw].[datein] >= '20200401 00:00:00' AND [pw].[datein] <= '20200630 23:59:59',它的工作速度会非常慢。10分钟vs 1秒
更奇怪的是,如果我使用第一次约会'20200101 00:01:00‘,它的速度也很快。如果日期大于2020年3月10日,则运行速度非常慢(如果查询中日期类似于字符串,如果是变量,则运行良好)。
我有一个错误的查询吗?但是为什么它要和变量一起工作呢?或者是SQL Server的一些问题?
发布于 2020-07-04 16:48:49
这看起来像是一个统计问题。
SQL server将在表中构建一个值的直方图,以便了解要创建哪种查询计划。
例如,如果您有一个包含一百万行的表T,但列C的值始终为1,然后执行select * from T with C = 1,引擎将选择一个期望返回大量行的计划,因为直方图显示“从统计上讲,此表很可能包含大量C=1的行”。
或者,如果您有一个包含一百万行的表T,但是列C的值从来不是1,那么直方图将告诉引擎“查询select * from T where C = 1可能会返回很少的行,因此请选择一个针对少量行进行优化的计划”。
当列中的值发生重大更改,但直方图(统计信息)尚未更新时,可能会出现问题。然后,SQL可能会根据直方图选择一个计划,其中不同的计划会更好。在您的情况下,直方图可能不会向引擎指示存在任何大于2020年3月10日左右的值。统计数据问题在日期中相当常见,因为您经常插入getdate(),这意味着表中较新的行将包含以前从未见过的值,因此直方图在更新之前不会覆盖这些值。
只要您在数据库设置中启用了自动更新统计信息,SQL就会根据多个different triggers自动更新统计信息(这是一篇旧文章,较新版本的引擎可能稍有更改)。
您可以通过强制SQL更新表上的统计信息来确定这是否是问题所在。可以通过完全扫描表或对表进行采样来刷新统计信息。对于大型表,采样速度要快得多,但结果不会那么准确。
要找出统计数据是否是您的问题所在,请执行以下操作:
update statistics PW with fullscanhttps://stackoverflow.com/questions/62712903
复制相似问题