簡體   English   中英

為什么我的查詢這么慢? (SQL Server 2008全文搜索怪異)

[英]Why is my query so slow? (SQL Server 2008 full text search weirdness)

我有一個包含全文索引列MiddlePart 該表有大約600,000行。 以下查詢非常快(30個結果,<1秒):

select * from DomainName
where contains (MiddlePart, '"antiques*"')
    OR freetext(MiddlePart, 'antiques')

此查詢也非常快(5個結果,<1秒):

select * from DomainName
where (contains (MiddlePart, '"dog*"') OR freetext(MiddlePart, 'dog'))
    AND (contains (MiddlePart, '"training*"') OR freetext(MiddlePart, 'training'))

那么為什么這兩個查詢的速度都很慢? (90秒+我取消了查詢):

查詢A:

select * from DomainName
where contains (MiddlePart, '"antiques*"')
    OR freetext(MiddlePart, 'antiques')
union
select * from DomainName
where (contains (MiddlePart, '"dog*"') OR freetext(MiddlePart, 'dog'))
    AND (contains (MiddlePart, '"training*"') OR freetext(MiddlePart, 'training'))

查詢B:

select * from DomainName
where (contains (MiddlePart, '"antiques*"')
    OR freetext(MiddlePart, 'antiques'))
OR
    ((contains (MiddlePart, '"dog*"') OR freetext(MiddlePart, 'dog'))
    AND (contains (MiddlePart, '"training*"') OR freetext(MiddlePart, 'training')))

編輯

QUERY A的全文計划:

|--Merge Join(Union)
   |--Nested Loops(Inner Join, OUTER REFERENCES:(FulltextMatch.[docid], [Expr1055]) WITH ORDERED PREFETCH)
   |    |--Stream Aggregate(GROUP BY:(FulltextMatch.[docid]))
   |    |    |--Merge Join(Concatenation)
   |    |         |--Table-valued function
   |    |         |--Table-valued function
   |    |--Clustered Index Seek(OBJECT:([domaining].[dbo].[DomainName].[PK__DomainNa__3214EC2708EA5793]), SEEK:([domaining].[dbo].[DomainName].[ID]=FulltextMatch.[docid]) ORDERED FORWARD)
   |--Merge Join(Left Semi Join, MERGE:([domaining].[dbo].[DomainName].[ID])=(FulltextMatch.[docid]), RESIDUAL:([domaining].[dbo].[DomainName].[ID]=FulltextMatch.[docid]))
        |--Nested Loops(Inner Join, OUTER REFERENCES:(FulltextMatch.[docid], [Expr1056]) WITH ORDERED PREFETCH)
        |    |--Stream Aggregate(GROUP BY:(FulltextMatch.[docid]))
        |    |    |--Merge Join(Concatenation)
        |    |         |--Table-valued function
        |    |         |--Table-valued function
        |    |--Clustered Index Seek(OBJECT:([domaining].[dbo].[DomainName].[PK__DomainNa__3214EC2708EA5793]), SEEK:([domaining].[dbo].[DomainName].[ID]=FulltextMatch.[docid]) ORDERED FORWARD)
        |--Merge Join(Concatenation)
             |--Table-valued function
             |--Table-valued function

查詢B的全文計划:

|--Nested Loops(Left Semi Join, OUTER REFERENCES:([domaining].[dbo].[DomainName].[ID]))
   |--Clustered Index Scan(OBJECT:([domaining].[dbo].[DomainName].[PK__DomainNa__3214EC2708EA5793]))
   |--Concatenation
        |--Table-valued function
        |--Nested Loops(Left Semi Join)
        |    |--Concatenation
        |    |    |--Table-valued function
        |    |    |--Table-valued function
        |    |--Row Count Spool
        |         |--Concatenation
        |              |--Table-valued function
        |              |--Table-valued function
        |--Table-valued function

由於您沒有為組合查詢包含SHOWPLAN,我猜它沒有輸出一個,這將指向優化器中的錯誤。 眾所周知,這在其他地方會發生。

無論如何,當遇到這樣的陌生時,臨時表總是一個值得尊敬的選擇:

select * into #a from DomainName
where contains (MiddlePart, '"antiques*"')
    OR freetext(MiddlePart, 'antiques')

select * into #b from DomainName
where (contains (MiddlePart, '"dog*"') OR freetext(MiddlePart, 'dog'))
    AND (contains (MiddlePart, '"training*"') OR freetext(MiddlePart, 'training'))

select * from #a union #b

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM