¿Cómo aumentar el rendimiento de las consultas vírgenes en MS SQL Server?

10

Tengo un sitio web ASP.NET que hace su propio almacenamiento en caché independiente de datos y los datos no cambian durante largos períodos de tiempo, por lo que no es necesario consultar SQL Server por segunda vez con la misma consulta. Necesito mejorar el rendimiento de las consultas por primera vez (vírgenes) que van a ese servidor SQL. Algunas consultas procesan tantos datos que pueden provocar el uso de SQL Server tempdb. No uso variables de tabla temporal o tablas temporales, por lo que SQL Server decide usarlo tempdbsolo cuando sea necesario.

Mi tamaño de base de datos es de 16 Gb, tengo 32 Gb de RAM física disponible en mi máquina servidor.

Entiendo que la estrategia de almacenamiento en caché de MS SQL Server intenta mantener los datos en la RAM para acelerar el rendimiento de consultas similares si necesitan volver a cargar los mismos datos. Además de eso, intentará usar la RAM disponible en lugar de tempdb para acelerar el rendimiento sin causar acceso al disco.

Supongo que cuando la consulta que necesita almacenar algo en tempdb SQL Server viene y no hay suficiente RAM disponible, SQL Server tiene 2 opciones:

1) descargar algunos datos almacenados en caché y usar RAM ahorrada en lugar de tempdb para evitar escrituras en disco

2) mantenga los datos en caché para futuras consultas y comience a usar tempdb, lo que hace que las escrituras ralenticen el disco.

No sé qué opción tomará SQL Server en esta situación, pero me gustaría que tome la opción # 1 porque solo me importa el rendimiento de las consultas (vírgenes) por primera vez, porque nunca vuelvo a enviar la misma consulta a SQL Server (aunque puedo enviar una consulta similar).

¿Cuál es la estrategia de almacenamiento en caché de SQL Server para este escenario?

¿Cómo equilibra el uso de RAM entre evitar tempdb para consultas vírgenes y la velocidad de consultas por segunda vez?

¿Es posible configurar SQL Server de tal manera que elija # 1? Si es así, entonces cómo ?

¿De qué otra forma puedo aumentar el rendimiento de todas las consultas vírgenes de SQL?

Como no conozco la estrategia de almacenamiento en caché de SQL Server, quiero colocar la base de datos en el disco RAM. Esto asegurará que cualquier consulta virgen tenga una alta velocidad de carga de datos no almacenados en caché, incluso si SQL Server siempre elige la opción # 1. El riesgo de esto es que SQL Server pueda comenzar a usar más tempdb con menos RAM disponible (solo quedan 16 Gb después de usar 16 Gb para RAM Disk) si continúa haciendo la opción # 2, lo que ralentizará las consultas vírgenes que causan derrames tempdb.

Estoy interesado en la solución para SQL 2008 R2, pero supongo que probablemente sea lo mismo para SQL 2008, SQL 2005 y puede ser SQL 2000.

Aclaraciones:

No hay otras aplicaciones ejecutándose en ese cuadro, está dedicado a SQL Server . El sitio web se ejecuta en una caja separada.

Es SQL Server 2008 R2 Standard Edition 64 bit en Windows Server 2008 R2 Enterprise 64 bit.

Solo ejecuto consultas de solo lectura y la base de datos está configurada para ser de solo lectura .

Supongamos que ya hay buenos índices . Esta pregunta es sobre SQL Server haciendo la elección n. ° 1 frente a la elección n. ° 2, cómo lo hace, si hay una manera de controlarlo y si RAM Disk lo ayuda a tomar la decisión correcta para consultas vírgenes.

alpav
fuente
¿Qué te hace pensar que tempdb se está utilizando aunque no estés creando tablas temporales? ¿Está utilizando distintas o agrupar por tablas?
Darin estrecho
3
32/64 bit? ¿Físico o virtual? ¿Este servidor está dedicado a SQL Server o también está ejecutando IIS u otras aplicaciones en el mismo cuadro? ¿Has hecho algún análisis del plan de ejecución de consultas? ¿Puedes publicar consultas de ejemplo y / o planes de ejecución? Y uno más por suerte ... siga la guía de Kendra para iniciar sesión sp_whoisactive mientras se ejecuta su consulta de problema y publique el resultado.
Mark Storey-Smith
@darinstrait La explicación más probable sería un derrame de tipo hash.
Mark Storey-Smith

Respuestas:

7

Su pregunta puede reformularse básicamente como "¿Cómo funciona la concesión de memoria de consulta?". Una buena lectura sobre el tema es Entender la concesión de memoria del servidor SQL . Antes de que una consulta se inicie en ejecución, puede requerir una concesión de memoria para géneros y hashes y otras operaciones con mucha memoria. Esta concesión de memoria es una estimación . Según el estado actual del sistema (número de solicitudes en ejecución y pendientes, memoria disponible, etc.), el sistema otorga a la consulta una concesión de memoria hasta la cantidad requerida. Una vez que se otorga la memoria, la consulta comienza a ejecutarse (puede que tenga que esperar en la esperada cola del "semáforo de recursos" antes de obtener la concesión). En la ejecución se garantiza la concesión de memoriapor el sistema Esta cantidad de memoria puede compartirse con páginas de datos (ya que siempre pueden vaciarse en el disco) pero nunca con otro uso de memoria (es decir, no puede estar sujeta a "robo"). Entonces, cuando la consulta comienza a solicitar memoria comprometida de su concesión, el motor desplegará lo que usted llama 'estrategia # 1': las páginas de datos pueden ser expulsadas (enjuagadas si están sucias) para darle a la consulta la memoria que se prometió. Ahora, si la estimación era correcta y la concesión era el 100% de la memoria solicitada, la consulta no debería "derramarse". Pero si la estimación era incorrecta (se reduce a estimaciones de cardinalidad, por lo tanto, está sujeta a estadísticas obsoletas) o si la consulta no obtuvo toda la concesión que había solicitado, la consulta se 'derramará'. Esto es cuando tempdb entra en escena y el rendimiento suele ser tanques.

El único mando que tiene a su disposición que controla algo en este proceso es el regulador de recursos . Dado que el RG se puede usar para especificar una configuración MIN para un grupo, se puede usar para reservar memoria para una determinada carga de trabajo de modo que realmente obtenga la concesión de memoria que solicita. Por supuesto, después de que realizó la investigación adecuada que muestra que las concesiones de memoria reducidas son las culpables, y por supuesto después de que se evaluó el impacto en otras cargas de trabajo. Y probado, por supuesto.

Ahora volvamos a su pregunta original. Si su investigación es correcta (un muy grande si) me gustaría señalar dos problemas:

  • ejecuta consultas de producción que requieren concesiones de memoria para un sitio web . Este es un gran no-no. Las concesiones de memoria son indicativas de consultas analíticas que no tienen lugar para atender solicitudes HTTP.
  • sus consultas probablemente no reciban la concesión de memoria que solicitan. Nuevamente, incluso más de un no-no para una carga de trabajo crítica de latencia como lo son los sitios web.

Entonces, lo que eso me dice es que tienes un problema fundamental de diseño y arquitectura. Los sitios web se basan en la latencia y deberían crear una OLTP como la carga de trabajo, sin concesiones de memoria y sin presión de memoria en las consultas. Sin mencionar que no hay derrames. Las consultas analíticas deben ejecutarse en trabajos fuera de línea y almacenar los resultados preprocesados ​​para una disponibilidad rápida cuando las solicitudes HTTP lo deseen.

Remus Rusanu
fuente
@Mark: la mayoría de las consultas no requieren concesión de memoria. Solo unos pocos operadores (más notablemente sort y hash join) necesitan un búfer de trabajo y, por lo tanto, solicitan una subvención. Esta es la 'nomenclatura' estándar. Puede estar pensando en el entorno de ejecución y el plan de ejecución de consultas, de los cuales cada consulta requiere uno e incluye algo de memoria. Una concesión de memoria es mucho más grande (MB). En segundo lugar, mira sys.dm_exec_query_memory_grants: tienes requested(el máximo), required(el mínimo) y granted(el real).
Remus Rusanu
Disculpas Había recogido en algún lugar que el mínimo por consulta se asignaba desde el mismo empleado de memoria, lo cual era incorrecto.
Mark Storey-Smith
Todavía no estoy seguro de estar de acuerdo con tus dos puntos. Todo tipo de operaciones triviales y hash join requiere subvenciones al nivel mínimo, por lo que sugerir que deben eliminarse por completo parece excesivo. Que los derrames a tempdb de las subvenciones insuficientes son una señal de alerta ciertamente es razonable, pero una prohibición general de cualquier operación que requiera una subvención podría poner a muchas personas en un camino innecesario de optimización preventiva.
Mark Storey-Smith
OP afirma que tiene todos los índices necesarios. Si eso es cierto y la carga de trabajo tiene suficientes problemas de concesión de memoria (e incluso derrames) como para ser notable, entonces diría que la carga de trabajo es demasiado analítica para un sitio web . En última instancia, la optimización del rendimiento es siempre un juego de investigación para determinar la causa raíz. Todas las declaraciones generales y prohibiciones siempre van a encontrar un contraejemplo que demuestra que están equivocadas, eso es un hecho. ¿El OP tiene un problema de diseño que crea una carga de trabajo demasiado analítica? No lo sé. ¿Creo que sí? Yo diría que 87.5% de confianza sí.
Remus Rusanu
@Remus: Su suposición fue buena, las consultas de mi sitio web son 100% analíticas. Permite a los usuarios construir cualquier consulta posible en la interfaz de usuario para enviar cualquier combinación posible de filtros, agregados y agrupaciones a SQL Server (lo que, por supuesto, dificulta la indexación). Sí, podría hacer que se ejecuten en modo asíncrono guardando resultados para su posterior recuperación, pero el objetivo es hacer que cualquier consulta se ejecute tan rápido que el resultado esté disponible inmediatamente después de 2-10 segundos y también la consulta analítica es la única función de ese sitio web , Creo que hacerlos asíncronos tiene sentido solo si hay otras consultas que no son analíticas.
alpav
3

Lo que no ha mencionado es qué tipo de consultas se ejecutan en la base de datos y si hay índices correctos para acelerar el rendimiento de sus consultas.

También debe asegurarse de que haya otras aplicaciones ejecutándose en el mismo cuadro. Aunque la caja tiene 32 GB de RAM, ¿ha configurado alguna configuración de memoria máxima en el servidor de la base de datos para poner un límite artificial? Si hay aplicaciones que se ejecutan en el mismo servidor, SQL y las otras aplicaciones pueden estar compitiendo por recursos y tenga en cuenta que SQL consume mucha memoria.

SQL Server usará tempdb para la ordenación interna o las combinaciones hash / agregados u operadores de cola, etc. y no puede controlar este comportamiento. Lo que puede hacer es limitar la cantidad de datos que se devuelven.

¿Ha marcado las estadísticas de espera en este cuadro? Cada vez que SQL Server está esperando un recurso, SQL Server rastreará el recurso de espera y buscará esa información ayuda.

Mire las consultas de diagnóstico de Glenn Berry y eso será un buen comienzo para usted.

También mire la PARAMETERIZACIÓN FORZADA como se menciona en http://weblogs.sqlteam.com/dang/archive/2009/06/27/Forced-Parameterization-A-Turbo-Button.aspx

Sankar Reddy
fuente
ok, supongamos que ya hay índices correctos. Olvidé mencionar que esta es una base de datos de solo lectura con consultas de solo lectura y no hay otra aplicación ejecutándose en el cuadro Servidor SQl.
alpav
¿Sus estadísticas están actualizadas? Las bases de datos de solo lectura no pueden crear estadísticas si faltan o están desactualizadas. ¿Sus datos están sesgados o tiene valores únicos para la clave? Hay muchos factores que pueden causar este comportamiento.
Sankar Reddy
¿Qué quieres decir con "este comportamiento"? No mencioné que algo va mal. Solo quiero aumentar el rendimiento en mis circunstancias especiales. SQL Server está optimizado para ejecutarse en cualquier situación, pero puede o no ejecutarse de la mejor manera en mi situación. No estoy seguro de si puedo confiar en SQL Server para hacer una elección equilibrada n. ° 1 vs n. ° 2. Cada vez que pongo nuevos datos, ejecuto sp_updatestats.
alpav
2
Cuando ejecuta sp_updatestats, ¿cuál es la proporción de muestra que eligió? La relación predeterminada es muy muestra y depende del tamaño del índice. Si sus consultas consultan principalmente (solo) los nuevos datos e incluso si hace sp_updatestats, SQL Server no puede tomar decisiones acertadas sobre los planes de ejecución.
Sankar Reddy
2

Esta pregunta actualmente se lee como una solución en busca de un problema. Has decidido que un disco RAM es la solución y quieres que alguien valide esa opción. Lo siento, no va a suceder.

Si ha medido y observado un derrame en tempdb, seguramente se deba a una operación de clasificación o hash y una concesión de memoria de consulta insuficiente. Dependiendo del volumen de datos a procesar, esto puede ser inevitable, pero hay buenas probabilidades de que la consulta y / o la indexación se puedan mejorar para evitarlo.

Eche un vistazo a Buffer Management para comprender mejor cómo SQL Server administra la memoria y SQL Server Memory Management Explicado para algunas herramientas básicas y consultas DMV para comprender dónde se asigna su memoria.

¿De qué otra forma puedo aumentar el rendimiento de todas las consultas vírgenes de SQL?

Este es un gran tema. Publique la consulta y el plan y obtendrá comentarios específicos.

Mark Storey-Smith
fuente