2010-02-12 19 views
6

¡Tengo un problema de rendimiento muy particular en el trabajo!¿Cómo mejorar el rendimiento en la tabla de SQL Server con campos de imagen?

En el sistema que estamos usando, hay una tabla que contiene información sobre el proceso de flujo de trabajo actual. Uno de los campos contiene una hoja de cálculo que contiene metadatos sobre el proceso (¡¡no me preguntes por qué !! y NO, NO PUEDO CAMBIARLO !!)

El problema es que esta hoja de cálculo se almacena en un campo de IMAGEN en un SQL Server 2005 (dentro de una base de datos establecida con compatibilidad SQL 2000).

Esta tabla tiene en la actualidad 22K + líneas e incluso una simple consulta como esta:

SELECT TOP 100 * 
    FROM OFFENDING_TABLE 

tarda 30 segundos para recuperar los datos en el Analizador de consultas.

Estoy pensando en actualizar la compatibilidad con SQL 2005 (una vez que me informaron que la aplicación puede manejarlo).

Lo segundo que estoy pensando es cambiar el tipo de datos de la columna a varbinary(max) pero no sé si esto afectará la aplicación.

Otra cosa que estoy considerando es usar sp_tableoption para establecer el large value types out of row a 1 ya que es actualmente 0, pero no tengo ninguna información si hacer esto mejorará el rendimiento.

¿Alguien sabe cómo mejorar el rendimiento en ese escenario?


Editado para aclarar

Mi problema es que no tengo ningún control sobre lo que la aplicación solicita al servidor SQL Server, y lo hice alguna reflexión sobre ella (la aplicación es una página web .NET 1.1) y utiliza el campo ofensivo para algunas cosas internas que no tengo idea de qué se trata.

Necesito mejorar el rendimiento general de esta tabla.

Respuesta

4

me gustaría recomendar que mira en el diseño de la mesa de salud infractor:

select * from sys.dm_db_index_physical_stats(
     db_id(), object_id('offending_table'), null, null, detailed); 

cosas también buscar son avg_fragmentation_in_percent, page_count, avg_page_space_used_in_percent, record_count y ghost_record_count. Pistas como alta fragmentación, o un alto número de registros fantasma, o un porcentaje bajo de página utilizada indican problemas y las cosas se pueden mejorar un poco con sólo la reconstrucción del índice de cero (es decir, la mesa.):

ALTER INDEX ALL ON offending_table REBUILD; 

Lo digo considerando que no puedes cambiar la mesa ni la aplicación. Si pudiera cambiar la tabla y la aplicación, el consejo que ya recibió es un buen consejo (no use "*", no seleccione "sin condición", use el tipo varbinary (max) más nuevo, etc.) .

También me gustaría ver la vida media de la página en los contadores de rendimiento para comprender si el sistema está hambriento de memoria. A partir de su descripción de los síntomas, el sistema se ve obligado a IO, lo que me lleva a pensar que hay poca memoria caché de páginas, y que podría necesitar más memoria RAM, así como un subsistema IO más rápido. En un sistema SQL 2008 también sugeriría activar la compresión de páginas, pero en 2005 no puede.
Y, para estar seguro, asegúrese de que las consultas no estén bloqueadas por la propia aplicación, es decir. la consulta no gasta el 90% de esos 30 segundos esperando un bloqueo de fila. Mire sys.dm_exec_requests mientras se está ejecutando la consulta, vea wait_time, wait_type y wait_resource. ¿Es PAGEIOLATCH_XX? ¿O es un candado? Además, ¿cómo está el sys.dm_os_wait_stats en su servidor? ¿Cuáles son las principales razones para esperar?

1

Una respuesta breve es hacer SELECT contra múltiples filas cuando los campos devueltos no incluyen el campo de imagen ofensivo, es decir, no SELECT *. Si desea el valor del campo de imagen, recupérelo caso por caso.

0

Establecer la opción de tipos de valor grande fuera de la fila definitivamente debería ayudar al rendimiento. El tamaño de la fila será significativamente menor, SQL Server puede hacer muchas menos lecturas físicas para acceder a la tabla.

2

En primer lugar - nunca haga un SELECT * en el código de producción - informando o no.

Usted tiene tres opciones básicas:

  • mover ese campo blob a cabo en una tabla separada si es que no siempre es necesario; Probablemente no es práctico ya que mencionas no se puede cambiar el esquema

  • ser más cuidadoso con sus SELECT declaraciones para seleccionar sólo aquellos campos que realmente necesita - y omitir el campo blob

  • ver si se puede limitar la consulta para incluir una cláusula WHERE y encontrar una manera de optimizar el plan de consulta por ej. la adición de un índice adecuado a la mesa (si es posible)

No hay magia "hacer esto más rápido" interruptor - pero se puede optimizar su consulta o optimizar su diseño de la mesa. Ambos ayudan. Si no puede cambiar nada, ni el diseño de la tabla, ni agregar un índice, ni cambiar las consultas, tendrá dificultades para optimizar cualquier cosa, me temo ...

Simplemente cambiando el campo a VARBINARY (MAX) no cambiará nada en absoluto; no se espera una mejora en el rendimiento solo por cambiar el tipo de datos.

Cuestiones relacionadas