首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SQL Server和/或SQL查询出现问题

问SQL Server和/或SQL查询出现问题
EN

Stack Overflow用户
提问于 2020-07-03 17:53:20
回答 1查看 83关注 0票数 2

我有这样的SQL查询:

代码语言:javascript
复制
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的一些问题?

EN

回答 1

Stack Overflow用户

发布于 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更新表上的统计信息来确定这是否是问题所在。可以通过完全扫描表或对表进行采样来刷新统计信息。对于大型表,采样速度要快得多,但结果不会那么准确。

要找出统计数据是否是您的问题所在,请执行以下操作:

代码语言:javascript
复制
update statistics PW with fullscan
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62712903

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档