在where子句中使用“OR”时,SQL Server全文搜索性能大幅下降

时间:2010-11-04 19:41:52

标签: sql sql-server tsql sql-server-2008 full-text-search

假设我有两个表tab1,tab2。在这两个表的所有varchar列上创建的全文索引。然后发出以下SQL:

SELECT *  
  FROM tab1 a 
  JOIN tab2 b on a.ID = b.ID
 WHERE CONTAINS(a.*, @keystring) 
    OR CONTAINS(b.*,@keystring)

这很慢(差不多30秒)。但是如果我发出以下SQL:

SELECT * 
  FROM tab1 a 
  JOIN tab2 b on a.ID = b.ID
 WHERE CONTAINS(a.*, @keystring) 

......或:

SELECT *  
  FROM tab1 a 
  JOIN tab2 b on a.ID = b.ID
 WHERE CONTAINS(b.*,@keystring)

表现相当不错(不到第二次)

如何解决此问题?

2 个答案:

答案 0 :(得分:2)

你试过了吗?

SELECT *  
  FROM tab1 a  
  JOIN tab2 b on a.ID = b.ID 
 WHERE CONTAINS(a.*, @keystring)  
UNION 
SELECT *   
  FROM tab1 a  
  JOIN tab2 b on a.ID = b.ID 
 WHERE CONTAINS(b.*,@keystring) 

如果您不关心键串是否同时存在重复项,请使用UNION all。

查看执行计划以查看差异,但OR经常会使查询运行得更慢。

答案 1 :(得分:1)

真正的问题是,如果“OR”到位,则无法选择正确的索引,因为“正确”索引将取决于每一行的第一次评估的结果。因此,DBMS选择一个索引(最可能是“OR”的第一部分的正确索引),并且如果第一个评估返回为“假”,则运行第二个未编制索引的索引。这使它变慢。这种表现在很大程度上取决于第一次评估返回的频率为“假”。