代码之家  ›  专栏  ›  技术社区  ›  Zenon

SQL Server 2005 FreeText()性能问题

  •  4
  • Zenon  · 技术社区  · 14 年前

    我有一个查询,其中有大约6-7个联接的表和一个FreeText()谓词,该谓词位于Where中基表的6列上。

    现在,这个查询在去年运行得很好(不到2秒钟),实际上保持不变(我尝试了旧版本,问题仍然存在)

    所以今天,突然之间,相同的查询大约需要1-1.5分钟。

    在检查了SQL Server 2005中的执行计划之后,重建了该表的全文索引,重新组织了全文索引,从头创建了索引,重新启动了SQL Server服务,重新启动了整个服务器,我不知道还要尝试什么。

    我暂时将查询切换为使用 LIKE 相反,直到我弄明白这一点(现在大约需要6秒钟)。

    当我在查询性能分析器中查看查询时,当我将“freetext”查询与“like”查询进行比较时,前者的读取次数是后者的350倍(4921261对13943),CPU使用量是后者的20倍(38937对1938)。

    所以,正是这个自由文本谓词导致了它的速度如此之慢。

    有人知道原因是什么吗?或者我可以做进一步的测试?

    [编辑]

    好吧,我只是再次运行查询以获得执行计划,现在它又需要2-5秒,没有对它做任何更改,尽管问题昨天仍然存在。这不是由于任何外部因素,因为上周四我第一次测试这个问题时,我已经停止了所有访问数据库的应用程序,所以这不是由于任何其他负载。

    好吧,我还是要包括执行计划,尽管现在一切都恢复了,这可能没什么帮助…注意,这是一个对遗留数据库的巨大查询,我无法更改(即规范化数据或删除一些不必要的中间表)。

    Query plan

    好的,这满了 query

    我可能得解释一下它到底是做什么的。基本上,它会得到招聘广告的搜索结果,其中有两种类型的广告,高级广告和普通广告。如果足够的话,结果被分页为每页25个结果,10个高级结果排在最前面,15个正常结果排在后面。

    因此,有两个内部查询根据需要选择尽可能多的高级/普通查询(例如,在第10页中,它获取了前100个高级查询和前150个普通查询),然后这两个查询与row_number()命令和一些数学交叉。然后按行号对组合进行排序,并返回查询。好吧,它在另一个地方被用来获取当前页面所需的25个广告。

    哦,整个查询是在一个巨大的遗留ColdFusion文件中构建的,由于它运行得很好,到目前为止我还不敢考虑/更改大的部分……千万不要触摸正在运行的系统等等;)只是一些小东西,比如改变中央WHERE子句的位。

    该文件还生成其他查询,这些查询基本上是相同的,但没有溢价/非溢价区别,以及此查询的许多其他变体,因此我不太确定其中一个更改如何更改其他查询…

    好吧,由于问题还没有出现,我给了马丁一笔奖金,因为他是迄今为止最有用的,我不希望奖金不必要地到期。感谢大家的努力,如果再次发生,我将尝试您的建议:)

    2 回复  |  直到 14 年前
        1
  •  1
  •   Martin Smith    14 年前

    这个问题可能是由于对全文查询将返回的结果数的基数估计不佳而引起的,这会导致联接操作的策略不佳。

    如果你把它分成两个步骤,你会如何发现它的性能?

    一个新步骤用全文查询的结果填充临时表或表变量,第二个步骤更改现有查询以引用临时表。

    (注意:您可能希望尝试加入或不加入 OPTION(RECOMPILE) 同时查看(a)返回多个结果的自由文本搜索词(b)只返回少数结果的查询计划。)

    编辑 在没有冒犯性的疑问的情况下,很难准确地澄清,但我的意思是不要做什么。

    SELECT <col-list>
    FROM --Some 6 table Join
    WHERE FREETEXT(...);
    

    这是怎么回事?

    DECLARE @Table TABLE
    (
    <pk-col-list>
    )
    INSERT INTO @Table
    SELECT PK
    FROM YourTable
    WHERE FREETEXT(...)
    
    SELECT <col-list>
    FROM --Some 6 table Join including onto @Table
    OPTION(RECOMPILE)
    
        2
  •  0
  •   GalacticJello    14 年前

    通常当我们遇到这个问题时,这是因为表碎片和有关索引的过时统计信息。

    下次,尝试执行 sp_updatestats 重建/重新索引后。

    Using Statistics to Improve Query Performance 更多信息。