Estou vendo algum comportamento estranho com a seguinte consulta T-SQL no SQL Server 2012:
SELECT Id
FROM dbo.Person
WHERE CONTAINS(Name, '"John" AND "Smith"')
ORDER BY Name
Somente a execução dessa consulta fornece cerca de 1.300 resultados em menos de dois segundos (existe um índice de texto completo Name
)
No entanto, quando altero a consulta para isso:
SELECT Id
FROM dbo.Person
WHERE CONTAINS(Name, '"John" AND "Smith"')
ORDER BY Name
OFFSET 0 rows
FETCH NEXT 10 ROWS ONLY
Demora mais de 20 segundos para me dar 10 resultados.
A seguinte consulta é ainda pior:
SELECT Id
FROM (
SELECT ROW_NUMBER() OVER (ORDER BY Name) AS RowNum, Id
FROM dbo.Person
WHERE CONTAINS(Name, '"John" AND "Smith"') ) AS RowConstrainedResult
WHERE RowNum >= 0 AND RowNum < 11
ORDER BY RowNum
Demora mais de 1,5 minutos para concluir!
Alguma ideia?
SELECT TOP 10 * .... ORDER BY Name
?Respostas:
Como você deseja apenas o
TOP 10
ordenado pelo nome, ele acha que será mais rápido trabalhar com o índicename
em ordem e verificar se cada linha corresponde aoCONTAINS(Name, '"John" AND "Smith"') )
predicado.Presumivelmente, são necessárias muitas outras linhas para encontrar as 10 correspondências necessárias e, em seguida, o esperado e esse problema de cardinalidade é agravado pelo número de pesquisas principais.
Um truque rápido para interrompê-lo usando esse plano seria alterar o
ORDER BY
para,ORDER BY Name + ''
embora o usoCONTAINSTABLE
em conjunto comFORCE ORDER
também deva funcionar.fonte
Parece uma estimativa errada de seletividade clássica. Não sei ao certo o que pode ser feito, pois o "driver" da consulta é a pesquisa de texto completo, que você não pode aumentar com as estatísticas.
Tente reescrever o
where contains
predicado em uminner join containstable
( CONTAINSTABLE ) e aplique dicas de ordem de junção para forçar a forma do plano.Essa não é uma solução perfeita porque tem problemas de manutenção, mas não vejo outra maneira.
fonte
Consegui resolver o problema:
Como eu disse na pergunta, havia indizes em todas as colunas + estatísticas para cada coluna. (Por causa das consultas LIKE herdadas), removi todos os indicadores e estatísticas, adicionei a pesquisa de texto completo e pronto, a consulta se tornou muito rápida.
Parece que os índices levaram a um plano de execução diferente.
Muito obrigado a todos pela ajuda!
fonte