Estou vendo um 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
A execução dessa consulta sozinha me fornece cerca de 1.300 resultados em menos de dois segundos (há um índice de texto completo em Name
)
No entanto, quando mudo 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 consulta a seguir é 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
Leva mais de 1,5 minutos para ser concluído!
Alguma ideia?
Como você deseja apenas o
TOP 10
ordenado por nome, ele acha que será mais rápido trabalhar no índicename
em ordem e verificar se cada linha corresponde aoCONTAINS(Name, '"John" AND "Smith"') )
predicado.Presumivelmente, são necessárias muito mais linhas para encontrar as 10 correspondências necessárias do que o esperado e esse problema de cardinalidade é agravado pelo número de pesquisas de chave.
Um hack rápido para pará-lo usando este plano seria alterar o
ORDER BY
para,ORDER BY Name + ''
embora o usoCONTAINSTABLE
em conjunto comFORCE ORDER
também deva funcionar.Isso se parece com a estimativa incorreta de seletividade clássica. Não tenho certeza do que pode ser feito sobre isso, pois o "driver" da consulta é uma pesquisa de texto completo que você não pode aumentar com estatísticas.
Tente reescrever o
where contains
predicado para 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.
Consegui resolver o problema:
Como eu disse na pergunta, havia índices em todas as colunas + estatísticas para cada coluna. (Por causa das consultas LIKE herdadas) removi todos os índices e estatísticas, adicionei a pesquisa de texto completo e voilà, a consulta tornou-se muito rápida.
Parece que as indizes levaram a um Plano de Execução diferente.
Muito obrigado a todos pela vossa ajuda!