J'ai une table avec une colonne indexée en texte intégral MiddlePart
. La table compte environ 600 000 lignes. La requête suivante est très rapide (30 résultats, < 1 seconde):Pourquoi ma requête est-elle si lente? (Bizarrerie de recherche de texte intégral SQL Server 2008)
select * from DomainName
where contains (MiddlePart, '"antiques*"')
OR freetext(MiddlePart, 'antiques')
Cette requête est également très rapide (5 résultats, < 1 seconde):
select * from DomainName
where (contains (MiddlePart, '"dog*"') OR freetext(MiddlePart, 'dog'))
AND (contains (MiddlePart, '"training*"') OR freetext(MiddlePart, 'training'))
Alors pourquoi sont à la fois ces requêtes DÉPASSE Lentement? (90 secondes + et j'annulé la requête):
Recherche 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'))
Recherche 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')))
EDIT
plan de texte complet pour 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
plan de texte intégral pour la requête 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
Avez-vous essayé de changer le premier à « UNION ALL » au lieu de « UNION »? Avez-vous regardé les plans de requête? L'utilisation de prédicats "OR" peut vraiment gâcher un plan de requête. – Pointy
Pourriez-vous s'il vous plaît signaler les plans de requête pour les requêtes? Il suffit de lancer 'SET SHOWPLAN_TEXT ON', puis d'exécuter les requêtes. – Quassnoi
@OMGPonies: "J'ai une table avec une colonne indexée en texte intégral" MiddlePart "" :) – Quassnoi