Pregunta

La tabla Producto 700K tiene registros en el mismo. La consulta:

SELECT TOP 1 ID, Name FROM Product WHERE contains(Name, '"White Dress"') ORDER BY DateMadeNew desc

tarda aproximadamente 1 minuto para correr. Hay un índice no agrupado en el índice DateMadeNew y FreeText en Nombre.

Si quito TOP 1 o Ordenar por -. Se tarda menos de 1 segundo para correr

Aquí está el enlace al plan de ejecución. http://screencast.com/t/ZDczMzg5N

Las apariencias como FullTextMatch cuenta con más de 400 mil ejecuciones. ¿Por qué está pasando esto? ¿Cómo se puede hacer más rápido?

ACTUALIZACIÓN 5/3/2010

Las apariencias como cardinalidad está fuera de control en las búsquedas de texto libre de múltiples palabras:

Optimizador estima que hay 28K registros que contengan 'vestido blanco', mientras que en realidad sólo hay 1. http://screencast.com/t/NjM3ZjE4NjAt

Si sustituyo 'vestido blanco' con 'White', el número estimado es de 27, 951' , mientras que el número real es de '28, 487' , que es mucho mejor.

Parece que Optimizer está utilizando sólo la primera palabra en la frase que se busca cardinalidad.

¿Fue útil?

Solución

Editar

http://technet.microsoft.com/en- es / library / cc721269.aspx # _Toc202506240

Lo más importante es que el correcta tipo de combinación es recogido por consulta de texto completo. cardinalidad la estimación de la FulltextMatch STVF es muy importante para el plan de la derecha. Así que la primera cosa a comprobar es la la estimación de cardinalidad FulltextMatch. Este es el número estimado de éxitos en el índice para la búsqueda de texto completo cuerda. Por ejemplo, en la consulta de La figura 3 esto debe estar cerca de la número de documentos que contengan la ‘Palabra’ plazo. En la mayoría de los casos lo que debería ser muy precisa, pero si la estimación estaba fuera por un largo camino, usted podría generar malos planes. La estimación para términos individuales es normalmente muy bueno, pero la estimación de varios términos, tales como frases o y consultas resulta más complejo ya que no es posible saber lo la intersección de los términos en el índice se basará en la frecuencia de la términos en el índice. Si la cardinalidad estimación es bueno, un mal plan probablemente es causada por la consulta modelo de costos optimizador. La única manera de solucionar el problema plan es utilizar una consulta alusión a la fuerza de un cierto tipo de combinación u optimizar PARA.

Por lo tanto, simplemente no puede saber a partir de la información que almacena si los términos de búsqueda 2 juntos son propensos a ser bastante independiente o comúnmente encontrado juntos. Tal vez debería tener 2 procedimientos separados uno para consultas de una sola palabra que permita que el optimizador de hacer sus cosas en y uno para los procedimientos de múltiples palabras que se fuerza un plan "lo suficientemente bueno" en (sys.dm_fts_index_keywords podría ayudar si usted no quiere una una talla para todos plan).

Nota:. Su único procedimiento palabra probablemente necesitará la opción CON RECOMPILE mirando este bit del artículo

En SQL Server 2008 búsqueda de texto completo que tenemos la capacidad de alterar el plan que se genera en base a una estimación de cardinalidad del término de búsqueda utilizado. Si se fija el plan de consulta (como lo es en una consulta con parámetros dentro de un procedimiento almacenado), este paso no se realiza. Por lo tanto, el plan compilado siempre sirve esta consulta, incluso si este plan no es ideal para un término de búsqueda determinado.

Respuesta original

Su nuevo plan todavía se ve bastante mala. Parece como si sólo se está volviendo 1 fila de la parte completa consulta de texto, pero el escaneo de todos los 770159 filas de la tabla del producto.

¿Cómo realizar esta?

CREATE TABLE #tempResults
(
ID int primary key,
Name varchar(200),
DateMadeNew datetime
)

INSERT INTO #tempResults
SELECT 
      ID, Name, DateMadeNew 
      FROM Product 
      WHERE contains(Name, '"White Dress"')


SELECT TOP 1
    *
    FROM #tempResults
    ORDER BY DateMadeNew desc

Otros consejos

No se puede ver el plan de ejecución vinculado, la policía de red que están bloqueando, así que esto es sólo una suposición ...

si se está ejecutando rápido sin la TOP y ORDER BY, trate de hacer esto:

SELECT TOP 1
    *
    FROM (SELECT 
              ID, Name, DateMadeNew 
              FROM Product 
              WHERE contains(Name, '"White Dress"')
         ) dt
    ORDER BY DateMadeNew desc

Las apariencias como FullTextMatch cuenta con más de 400 mil ejecuciones. ¿Por qué sucede esto?

Ya que tiene un índice combinado con TOP 1, optimizador piensa que va a ser mejor para atravesar el índice, comprobando cada registro para la entrada.

¿Cómo se puede hacer más rápido?

Si la actualización de las estadísticas no ayuda, trate de añadir un toque a su consulta:

SELECT  TOP 1 *
FROM    product pt
WHERE   CONTAINS(name, '"test1"')
ORDER BY
        datemadenew DESC
OPTION (HASH JOIN)

Esto obligará a que el motor se utilice un algoritmo HASH JOIN a unirse a su mesa y el resultado de la consulta de texto completo.

consulta

Texto completo es considerado como una fuente remota devolver el conjunto de valores indexados por KEY INDEX proporcionado en la definición FULLTEXT INDEX.

Actualización:

Si sus usos ORM parametrizar consultas, puede crear una guía de plan.

  • Uso de perfiles para interceptar la consulta que envía el ORM textualmente
  • Generar un plan correcto en SSMS uso de sugerencias y guardarlo como XML
  • Uso sp_create_plan_guide con un OPTION USE PLAN para forzar al optimizador utilice siempre este plan.

Yo tenía el mismo problema anterior.

El rendimiento depende de qué índice único que elija para la indexación de texto completo. La tabla tiene dos columnas únicas -. ID y article_number

La consulta:

select top 50 id, article_number, name, ... 
from ARTICLE 
CONTAINS(*,'"BLACK*" AND "WHITE*"')
ORDER BY ARTICLE_NUMBER

Si el índice de texto completo está conectado a ID entonces es lenta en función de las palabras buscadas. Si el índice de texto completo está conectado al índice ARTICLE_NUMBER UNIQUE entonces era siempre rápido.

Tengo una mejor solución.

I. primera visión general de Let propone soluciones, ya que también se pueden usar en algunos casos:

  1. OPCIÓN (hash) - no es bueno ya que puede tener errores "procesador de consultas no pudo producir un plan de consulta a causa de las pistas definidas en esta consulta Volver a enviar la consulta sin especificar ninguna pista y fuera. utilizando FORCEPLAN SET ".

  2. SELECT * FROM TOP 1 (ORIGINAL_SELECT) ORDER BY ... - no es bueno, cuando es necesario utilizar la paginación de resultados que ORIGINAL_SELECT

  3. sp_create_plan_guide - no es bueno, en cuanto a su uso plan_guide tienes que salvar el plan de una identificación exacta de SQL, este no funcionará para las sentencias de SQL dinámico (por ejemplo, generados por ORM)

II. Mi solución contiene de dos partes 1. Auto unirse tabla que se utiliza para la búsqueda de texto completo 2. Uso HASH MS SQL sugerencias de combinación MSDN sugerencias de combinación

Su SQL:

SELECT TOP 1 ID, Name FROM Product WHERE contains(Name, '"White Dress"') 
ORDER BY DateMadeNew desc

En caso de ser reescrita como:

SELECT TOP 1 p.ID, p.Name FROM Product p INNER HASH JOIN Product fts ON fts.ID = p.ID
WHERE contains(fts.Name, '"White Dress"') 
ORDER BY p.DateMadeNew desc

Si está utilizando NHibernate con / sin Castillo activos Records, he respondido en posterior cómo interceptor de escritura para modificar la consulta para reemplazar INNER JOIN por interno hash

Un par de pensamientos en este caso:

1) ¿Ha actualizado las estadísticas de la tabla del producto? Sería útil para ver las estimaciones y el número real de filas en las operaciones allí también.

2) ¿Qué versión de SQL Server está utilizando? Tenía un problema similar con SQL Server 2008 que resultó ser nada más que no tener instalado el Service Pack 1. Instalar el SP1 y una consulta de texto libre que se estaba produciendo un par de minutos (debido a un gran número de ejecuciones reales contra real) descendieron a tomar un segundo.

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