2008-11-08 6 views
20

Jeff Atwood escribió sobre este here, y si bien entiendo el aumento del rendimiento teórico que podría ofrecer un procedimiento almacenado, parece un dolor tremendo.¿Los procedimientos almacenados realmente mejoran el rendimiento en MS SQL/.NET?

¿Qué tipos de consultas vería que el mayor rendimiento aumenta con los procedimientos almacenados, y qué tipos de consultas prefiere construir sobre la marcha?

Cualquier documentación de una manera u otra sería muy apreciada.

Respuesta

37

El argumento de proc/no almacenados proc almacenados se ha convertido en un tema religioso. Para cada persona que enfatiza planes de ejecución optimizados para procs, otro señala que las consultas dinámicas comunes se almacenan en caché y se optimizan en la mayoría de los DBMS modernos. Para cualquiera que señale la seguridad que un proceso puede ofrecer, otro explica que las consultas dinámicas se pueden realizar igual de seguras. A algunos les gusta la flexibilidad de cambiar un proceso sin volver a compilar su aplicación, mientras que otros argumentan que las consultas se deben capturar en el código de la aplicación para que vivan y crezcan en la misma base de código.

digo ...

Haz lo que quieras. Dudo que podamos encontrar la respuesta correcta. Si los procs son una molestia, no los use. Si parecen una buena idea, ve por ello. He trabajado con ambos modelos y sinceramente no tengo una preferencia. Soy productivo con o sin ellos.

+0

Eso alivia mucha presión en realidad, gracias. Creo que, en general, todavía quiero saber si hay alguna diferencia y cuál es la diferencia (documentada), pero esta es una gran filosofía .... Me pregunto si mi equipo buscará eso :-P –

+0

Estoy de acuerdo con usted, sin embargo, sobre la naturaleza religiosa de la pregunta, y casi no la pregunté. Pero creo que, como buenos programadores, debemos comprender exactamente qué está pasando con cada componente del sistema en caso de que necesitemos un rendimiento extremo. –

+2

Buena respuesta. Pero es mejor comprender los detalles sangrientos para que puedas justificar la ruta que elijas. Vea mi respuesta para algunos de esos detalles. – RoadWarrior

0

La idea de que los procedimientos almacenados sean más rápidos es que pueden almacenar planes de consultas en caché, como precompilar el procedimiento almacenado. Entonces, si el procedimiento es muy complejo con muchas combinaciones entre muchas tablas, es posible que vea un beneficio de velocidad.

Creo que los procesos almacenados son necesarios por más de su velocidad, ayudan a abstraer el esquema de la base de datos y ayudan a prevenir ataques de inyección sql.

+0

Sé que tiene 3 años en este momento, pero para la posteridad: no hay nada sobre un sproc que lo ayude a prevenir la inyección de SQL. –

2

Frans Bouma caused a stir hace un tiempo con este tema.

En SQL Server, es más importante entender que cualquier aumento en el rendimiento se debe al plan de consulta que se almacena en caché. Un plan de consulta es bastante costoso de compilar, por lo que tiene sentido almacenarlos en caché. EDITAR: es menos probable que el SQL Ad-hoc coincida con un plan de consulta en caché. El SQL dinámico se puede almacenar en caché si se ejecuta llamando a sp_executesql.

Si utiliza EXEC para ejecutar SQL, por ejemplo,'EXEC @dynamic_sql ', almacenará en caché un plan pero no lo parametrizará (ni lo normalizará), lo que significa que a menos que se envíe exactamente la misma consulta no volverá a utilizar el plan de consulta en caché.

+0

Pero use sp_ExecuteSQL y lo hará –

+0

Pero sp_executesql es bastante oscuro y completa la sobrecarga solo con el fin de almacenar en caché un plan de ejecución. – RoadWarrior

2

Procedimientos almacenados Los procedimientos que proporcionan un beneficio de rendimiento son un mito de las versiones anteriores de SQL Server. SQL Server> versión 7 trata todas las consultas de la misma manera y guardará en caché los planes de ejecución para todas las consultas de uso común, sin importar su origen.

Me pregunto cuántos años más vivirá este mito.

+0

¿Puede proporcionar documentación de esto? –

+0

http://www.sommarskog.se/dynamic_sql.html: Si usa EXEC para ejecutar SQL, por ejemplo,'EXEC @dynamic_sql ', almacenará en caché un plan, pero no lo parametrizará (ni lo normalizará), lo que significa que a menos que sea exactamente el se envía la misma consulta, no volverá a utilizar el plan de consulta en caché. –

+0

Buen enlace, mitch. – dkretz

0

Un procedimiento almacenado mal escrito no aumentará el rendimiento. Lo mismo que una mala consulta en línea tendrá un peor rendimiento que uno mal pensado.

6

Las mayores ventajas de los procedimientos almacenados, en mi opinión, son los siguientes:

1/están centralizados en el sistema de gestión de base de datos para los administradores de bases saben exactamente lo que están haciendo y pueden optimizar la base de datos para adaptarse a ellos. Las consultas ad-hoc de los clientes son mucho más difíciles de hacer. He visto las bases de datos arrodilladas porque los DBA permitían consultas sin restricciones.También obligan a los clientes a pensar en lo que necesitan.

2/Pueden hacer un procesamiento muy complicado en el servidor minimizando la cantidad de datos enviados a través del cable. Esto evita que las aplicaciones obtengan una gran cantidad de datos, decidan algo de ellos, luego obtengan más datos, y así sucesivamente.

Por supuesto, permita cualquier consulta aleatoria durante el desarrollo pero, antes de pasar a producción, determine qué acciones de la base de datos se deben mover a los procesos almacenados.

Como DBA a tiempo parcial, creo que eso significa todos ellos, pero no es necesario siempre y cuando se tenga un mínimo control sobre las consultas que pueden enviar las aplicaciones.

+0

No había pensado en el n. ° 2: el buen punto –

+0

n. ° 2 no es un factor que las personas que dicen usar dinámico estén de acuerdo contigo y lo señalan como ejemplos de que los procedimientos almacenados son la herramienta adecuada. –

14

En días pasados, había considerables beneficios de rendimiento de al utilizar procedimientos almacenados, pero la reutilización de planes de consulta ahora es significativamente mejor, de modo que los dos son casi los mismos en muchos casos.

Si está creando SQL dinámico en el servidor, puede aumentar aún más la reutilización del plan de consulta (y la seguridad de inyección) utilizando sp_ExecuteSQL (en lugar de solo EXEC) para ejecutar el SQL.

Hay algunas ventajas de utilizar procedimientos almacenados:

  • Fijan exactamente lo que sucederá en el db
  • Para los escenarios de fuertes medidas de seguridad, se puede controlar estrechamente el acceso al procedimiento almacenado (en lugar de la tabla)
  • puede subdividir la consulta si el plan va extraño en puntos (sniffing)

Sin embargo, hay ventajas a SQL también:

  • Permite herramientas ORM (LINQ, por ejemplo) para escribir consultas componibles (página 4, ordenados por Foo, Bar) sobre la marcha
  • Se le permite escribir código dinámico en un lenguaje más expresivo (TSQL en realidad no es destinado a ser utilizado para escribir TSQL)
  • lo general, tienen mejor utillaje

Algunos cosa donde, sin duda utilizar un SP está en (por ejemplo) un paso a la migración de datos - es decir, para una operación masiva Podría usar SqlBulkCopy para insertar los datos en una tabla de etapas y luego un procedimiento almacenado para mover los datos. Más allá de eso, soy bastante flexible.

7

Hemos encontrado una ventaja de los Procedimientos almacenados es que una vez creados inicialmente por el Desarrollador, pueden entregarse a los expertos en DBA o Ajuste de la base de datos para que se escriban mejor por razones de rendimiento si es necesario.

Obviamente, los DBA no necesitan acceder al código de la aplicación y pueden trabajar junto con una versión de aplicación pendiente.

Concedido, lo mismo ocurre con las consultas SQL integradas o en línea, pero creo que los Procedimientos almacenados se prestan mejor a esta forma cooperativa y de equipo más grande.

+5

Persoanlly, me gustaría que mis "expertos en ajuste" sean desarrolladores regulares que entiendan el código de la aplicación. En particular, me gustaría que tengan acceso directo a las mismas pruebas de integración (que probablemente estén en C#, etc.). Además, muchas veces, la refacturación del código de la aplicación en sí es la mejor manera de mejorar el rendimiento. –

+0

Estoy de acuerdo con Marc, pero le di un +1, porque creo que la postura de Andrew es válida y útil. Bonito. –

+1

Aunque me gustaría que los desarrolladores lo ajustaran, la cruda realidad es que la mayoría de los desarrolladores no tienen la menor idea de cómo crear buenas consultas. Esta es la razón número uno para la existencia de linq. – NotMe

2

Una de las ideas detrás de un procedimiento almacenado es que le permite hacer varias cosas en un solo viaje a la base de datos.

MSSQL permite que los lotes de consulta se envíen en una sola solicitud; esto es más o menos equivalente.

Sin embargo, el principio es el mismo. En un sistema distribuido a gran escala, la latencia de la base de datos (en lugar del tiempo que tarda la consulta en el servidor) puede ser un problema de rendimiento. Emitir menos consultas puede ser beneficioso.

Por lo tanto, utilizar lotes de consulta o procedimientos almacenados frente a la emisión de consultas únicas es una ganancia de rendimiento potencial en un sistema distribuido.

10

Como es común con el software, el problema del almacenamiento en caché de SQL es más sutil de lo que parece. Por ejemplo, veamos el almacenamiento en caché de un ad-hoc de SQL consulta:

-- First, clear the cache 
DBCC FREEPROCCACHE 

-- Look at what executable plans are in cache 
SELECT sc.* 
FROM master.dbo.syscacheobjects AS sc 
WHERE sc.cacheobjtype = 'Executable Plan' 

-- Execute the following statement 
SELECT t.* 
FROM pubs.dbo.titles AS t 
WHERE t.price = 19.99 

-- Look at what executable plans are in cache and you'll 
-- find that there's a plan for a NUMERIC(4,2) 
SELECT sc.* 
FROM master.dbo.syscacheobjects AS sc 
WHERE sc.cacheobjtype = 'Executable Plan' 

-- If you execute the EXACT same statement with a 4,2 
-- then you will get THAT plan. But if you execute with a 5,2 
-- then you'll get a new plan. Try this: 
SELECT t.* 
FROM pubs.dbo.titles AS t 
WHERE price = 199.99 

-- Look again at the cached executable plans, and you'll see a NEW one... 
SELECT sc.* 
FROM master.dbo.syscacheobjects AS sc 
WHERE sc.cacheobjtype = 'Executable Plan' 

sin embargo se puede utilizar sp_executesql para escribir los parámetros y forzar el plan para ser almacenado en caché. Todos los usos posteriores tendrán el mismo plan, pero algunas personas no les gusta la oscuridad de este enfoque:

DECLARE @ExecStr nvarchar(4000) 
SELECT @ExecStr = N'SELECT t.* FROM dbo.titles AS t WHERE t.price = @price' 
EXEC sp_executesql @ExecStr, N'@price money', 19.99 

Ahora bien, si se crea una consulta similar a un procedimiento de almacenado con un parámetro para el precio, el plan se creará y almacenará en caché en la memoria (no en el disco) en la primera ejecución, y se reutilizará independientemente del valor del parámetro.

El hecho de que el plan de procedimiento almacenado esté almacenado en la memoria y no en el disco significa que se saldrá de la memoria caché en un reinicio del servidor o debido a una baja reutilización. También puede caerse de la memoria caché si los datos de los que depende el procedimiento cambian lo suficiente como para invalidar las estadísticas. Esto hace que SQL Server invalide el plan.

+0

+1 Gran respuesta, leí un poco sobre el tamaño de los parámetros, hinchando la memoria caché de proceso pero es un gran ejemplo para mostrar/vencer a la gente;) – Meff

0

Una cosa que la gente está omitiendo es que todos los procedimientos almacenados CRUD se llenan con coalescencia y si las declaraciones son extremadamente lentas.

Si está utilizando sentencias parametrizadas frente a una fusión mediante el procedimiento almacenado, las declaraciones dinámicas ganarán.

Cuestiones relacionadas