Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sql-server-2005/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 为什么多个WHERE条件会减慢查询速度,而不是加快查询速度?_Sql Server_Sql Server 2005_Tsql - Fatal编程技术网

Sql server 为什么多个WHERE条件会减慢查询速度,而不是加快查询速度?

Sql server 为什么多个WHERE条件会减慢查询速度,而不是加快查询速度?,sql-server,sql-server-2005,tsql,Sql Server,Sql Server 2005,Tsql,问题是,与使用一个或两个条件(而不是全部三个条件)运行的查询相比,所讨论的查询运行速度非常慢 现在是问题 Select Count(*) From SearchTable Where [Date] >= '8/1/2009' AND [Zip] In (Select ZipCode from dbo.ZipCodesForRadius('30348', 150)) AND FreeText([Description], 'keyw

问题是,与使用一个或两个条件(而不是全部三个条件)运行的查询相比,所讨论的查询运行速度非常慢

现在是问题

Select Count(*)
From 
    SearchTable 
Where 
    [Date] >= '8/1/2009' 
    AND 
    [Zip] In (Select ZipCode from dbo.ZipCodesForRadius('30348', 150))
    AND 
    FreeText([Description], 'keyword list here')  
第一个条件是不言自明的。第二种方法使用UDF获取30348英里范围内的邮政编码列表。第三种方法使用全文索引来搜索提供的单词

只有这个条件

[Date] >= '8/1/2009' 
查询在3秒内返回43884行(表大小略低于500k行)

仅使用此条件

[Zip] In (Select ZipCode from dbo.ZipCodesForRadius('30348', 150))
我得到27920,也在3秒内返回

只有全文部分

FreeText([Description], 'keyword list here')
68404将在8秒内返回

当我只使用邮政编码和全文条件时,我在4秒内得到4919个
仅日期和全文条件就可以在14秒内获得9481 使用日期和邮政编码条件仅在14秒内为我提供3238个

在这三个条件下,查询在2分53秒内返回723。(wtfbbq)

因为需要检查的条件越多,数据库引擎的工作量就越大。在我看来似乎合乎逻辑


如果在聚集索引字段上有一个条件,那么这个特定的检查不会使操作慢那么多。您是否考虑过重新排列索引以匹配您的查询?

从数据传输的角度来看,您的想法是正确的:数据越少,完成时间越快。但是,通常这段时间很短,大部分时间都花在实际的查询处理上


这样看:如果你在一个停车场,是更容易分辨出所有红色的车,还是所有红色的车,2006年款,黑色内饰,有橡胶地板垫的车?

知道原因的唯一方法是检查执行计划。 试试看。

  • 字符串操作(如FreeText)非常昂贵
  • ZipCodesForRadius函数也可能很昂贵,这取决于它的编码方式以及是否存在必要的索引
如果对WHERE子句进行排序不能加快速度,那么在select周围使用select可能会起到作用(在某些情况下,DB2/400会加快速度,但不确定SqlServer如何优化):


我怀疑Date字段没有索引,并且在对非sargable列应用where子句之前,如果没有可依赖的索引来过滤resultset,则会使它们的权重相等,并且在应用其他更昂贵的子句之前不会先执行快速过滤

当我无法使用索引等对数据库进行优化时,我经常会发现,重新编写类似于此的查询就足以指导编译器进行更高效的查询:

Select Count(*)
From (
    Select 1
    From SearchTable 
    Where [Zip] In (Select ZipCode from dbo.ZipCodesForRadius('30348', 150))
) 
Where [Date] >= '8/1/2009' 
    AND FreeText([Description], 'keyword list here')  

尝试向表中添加一些索引。特别是那些包含where条款中的条件的。最有可能的是,它现在正在进行一次表扫描,以将数据拉回来,这可能非常缓慢

此外,您可能希望使用ManagementStudio中的“包含实际执行计划”按钮来显示如何确定您获得的记录

更新


从您的一条评论中可以看出,此查询似乎是从临时表中提取的。在这种情况下,在创建表之后,对其应用索引。添加索引然后运行查询将比在500k行临时表上运行表扫描更快。

获取执行计划

您需要查看执行计划,以便有希望了解响应时间变化的真正原因。特别是在这种情况下,有几个因素需要考虑:

  • 有些查询返回更多行的速度可能更快,因为它们正在进行表扫描——每个人都会在其中钻取“表扫描速度慢”,但根据数据分布,执行表扫描的速度可能会快于50000行查找。在没有执行扫描的情况下,根本无法判断
  • 也可能是不正确的统计数据阻止了SQL server准确预测其预期返回的行数-如果SQL server预期返回20行,但实际上有20000行,那么在更复杂的查询中,很可能会以错误的顺序执行操作,从而导致非常慢的查询-同样,这只是如果没有执行计划,就无法判断
  • 特别是使用
    Freetext
    意味着正在使用全文搜索引擎,这可能会导致SQL server在预测返回的行数时出现其他问题
真的,准备一份执行计划

更新:

可能原因 在没有执行计划的情况下,我认为执行缓慢的最可能原因是对
ZipCode
Description
上的条件估计不足:

  • 很难估计
    ZipCode
    条件下的匹配数,因为其结果取决于存储过程
  • 根据全文查询引擎的结果,很难估计
    FreeText
    条件下的匹配数
我认为正在发生的事情是,SQLServer低估了过滤后保留的行数,并以错误的顺序应用了查询。结果是,它最终进行了数十(可能数百)数千次的查找,这远比仅仅进行表扫描慢得多

对于一个特别复杂的查询,我看到SQL server执行了约3000000次查找,试图返回一行—该表甚至没有3000000行

要尝试的事情-将ZipCodeForRadius放入临时表中。 如果我是对的,那么为了帮助您完成第一个任务,您可以尝试将
ZipCodesForRadius
存储过程的结果放入一个临时表中,我必须承认我没有这样做
Select Count(*)
From (
    Select 1
    From SearchTable 
    Where [Zip] In (Select ZipCode from dbo.ZipCodesForRadius('30348', 150))
) 
Where [Date] >= '8/1/2009' 
    AND FreeText([Description], 'keyword list here')