Veo un comportamiento extraño con la siguiente consulta T-SQL en SQL Server 2012:
SELECT Id
FROM dbo.Person
WHERE CONTAINS(Name, '"John" AND "Smith"')
ORDER BY Name
Ejecutar esta consulta solo me da unos 1.300 resultados en menos de dos segundos (hay un índice de texto completo Name
)
Sin embargo, cuando cambio la consulta a esto:
SELECT Id
FROM dbo.Person
WHERE CONTAINS(Name, '"John" AND "Smith"')
ORDER BY Name
OFFSET 0 rows
FETCH NEXT 10 ROWS ONLY
Me lleva más de 20 segundos darme 10 resultados.
La siguiente consulta es aún peor:
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
¡Tarda más de 1.5 minutos en completarse!
¿Algunas ideas?
SELECT TOP 10 * .... ORDER BY Name
?Respuestas:
Como solo desea el
TOP 10
ordenado por nombre, cree que será más rápido trabajar en el índicename
y ver si cada fila coincide con elCONTAINS(Name, '"John" AND "Smith"') )
predicado.Presumiblemente, se necesitan muchas más filas para encontrar las 10 coincidencias requeridas de lo que se espera y este problema de cardinalidad se ve agravado por la cantidad de búsquedas clave.
Un truco rápido para detenerlo usando este plan sería cambiar el
ORDER BY
aORDER BY Name + ''
aunque usarloCONTAINSTABLE
junto conFORCE ORDER
también debería funcionar.fuente
Esto se parece a la clásica estimación de la selectividad. No estoy seguro de qué se puede hacer al respecto, ya que el "controlador" de la consulta es una búsqueda de texto completo que no puede aumentar con estadísticas.
Intente reescribir el
where contains
predicado a uninner join containstable
( CONTAINSTABLE ) y aplique sugerencias de orden de unión para forzar la forma del plan.Esa no es una solución perfecta porque tiene problemas de mantenimiento, pero no puedo ver otra forma.
fuente
Me las arreglé para resolver el problema:
Como dije en la pregunta, había índices en todas las columnas + estadísticas para cada columna. (Debido a las consultas LIKE heredadas) Eliminé todos los índices y estadísticas, agregué la búsqueda de texto completo y voilà, la consulta se volvió realmente rápida.
Parece que los índices llevaron a un plan de ejecución diferente.
¡Muchas gracias a todos por su ayuda!
fuente