Pregunta

Tengo una consulta con unos 6-7 tablas combinadas y un FREETEXT () predicado en 6 columnas de la tabla base en el lugar.

Ahora, esta consulta funcionó bien (en menos de 2 segundos) durante el último año y prácticamente se mantuvo sin cambios (he intentado versiones antiguas y las persiste problema)

Así que hoy, de repente, la misma consulta tarda alrededor de 1-1,5 minutos.

Después de comprobar el plan de ejecución en SQL Server 2005, la reconstrucción del índice de texto completo de esa mesa, la reorganización del índice FULLTEXT, crear el índice desde cero, reiniciar el servicio de SQL Server, reiniciar todo el servidor no sé qué otra cosa intentarlo.

I conmuta temporalmente la consulta para uso LIKE lugar hasta que resolver esto (que toma alrededor de 6 segundos ahora).

Cuando miro a la consulta en el analizador de rendimiento de las consultas, cuando comparo la'FREETEXT'query con la consulta'LIKE', el primero tiene 350 veces más que lee (4.921.261 frente a 13943) y 20 veces (38.937 vs. . 1938) el uso de la CPU de este último.

Por lo que realmente es la'FREETEXT'predicate que hace que sea tan lento.

¿alguien tiene alguna idea de lo que podría ser la razón? O pruebas adicionales que podrían hacer?

[Editar]

Bueno, sólo corrió la consulta de nuevo para obtener el plan de ejecución y ahora se tarda 2-5 segundos más, sin los cambios realizados a la misma, aunque el problema todavía existía ayer. Y no se debió a factores externos, como me había dejado todas las aplicaciones que acceden a la base de datos la primera vez que probé el tema el jueves pasado, por lo que no se debía a ninguna otra carga.

Bueno, yo todavía incluye el plan de ejecución, aunque podría no ayuda mucho ahora que todo está funcionando de nuevo ... Y cuidado, que es una consulta a una base de datos enorme legado que no puedo cambio (es decir, normalizar datos o deshacerse de algunos cuadros intermedios innecesarios)

de planes de consultas

ok aquí está la plena consulta

Yo podría tener que explicar qué es exactamente lo que hace. básicamente se obtiene resultados de búsqueda de anuncios de trabajo, donde hay dos tipos de anuncios, las primas y los normales. los resultados están paginados a 25 resultados por página 10, las primas hasta la parte superior y 15 las normales después de eso, si hay suficientes.

así que hay los dos consultas internas que seleccionar tantos los de suscripción / normal como sea necesario (por ejemplo, en la página 10 que obtiene los premium parte superior 100 y Top 150 las normales), entonces esos dos consultas se intercalan con un comando () row_number y un poco de matemática. entonces la combinación es ordenado por rownumber y se devuelve la consulta. así se usa en otro lugar para obtener sólo los 25 anuncios necesarios para la página actual.

Ah, y toda esta consulta se construye en un archivo heredado Coldfusion enorme y como ha sido funcionando bien, no he atrevido thouching / cambio de grandes porciones hasta ahora ... nunca toque un sistema que ejecuta y así sucesivamente;) Sólo pequeña cosas como el cambio de bits de la central donde cláusula.

El archivo también genera otras preguntas que hacen básicamente lo mismo, pero sin la distinción de alta calidad premium / no y muchas otras variaciones de esta consulta, por lo que nunca estoy muy seguro de cómo un cambio en uno de ellos podría cambiar el otros ...

Ok ya que el problema no ha surgido de nuevo, me dio Martin la generosidad como él ha sido el más útil hasta ahora y yo no quería que la recompensa que expire innecesariamente. Gracias a todos los demás por sus esfuerzos, voy a tratar sus sugerencias si ocurre de nuevo:)

¿Fue útil?

Solución

Este problema puede surgir debido a una mala estimación de cardinalidad de la serie de resultados que será devuelto por la consulta texto completo que conduce a una mala estrategia para la operación JOIN.

¿Cómo se encuentra el rendimiento si usted lo rompe en 2 pasos?

Un nuevo paso que puebla una variable de tabla o tabla temporal con los resultados de la consulta de texto completo y el segundo cambio de la consulta existente para referirse a la tabla temporal en su lugar.

(Nota: Es posible que desee probar este JOIN con y sin OPTION(RECOMPILE) mientras busca en los planes de consulta para (A) un término de búsqueda de texto libre que devuelve muchos resultados (B) Uno que regresa sólo un puñado de resultados.)

Editar Es difícil aclarar exactamente en ausencia de la consulta infractor, pero lo que quiero decir es en lugar de hacer

SELECT <col-list>
FROM --Some 6 table Join
WHERE FREETEXT(...);

¿Cómo realizar esta?

DECLARE @Table TABLE
(
<pk-col-list>
)
INSERT INTO @Table
SELECT PK
FROM YourTable
WHERE FREETEXT(...)

SELECT <col-list>
FROM --Some 6 table Join including onto @Table
OPTION(RECOMPILE)

Otros consejos

Por lo general, cuando tenemos este problema, es debido a la fragmentación mesa y estadísticas rancias en los índices en cuestión.

La próxima vez, trate de EXEC sp_updatestats después de una reconstrucción / reindex.

El uso de estadísticas para mejorar rendimiento de las consultas para obtener más información.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top