¿Son los procedimientos almacenados más eficientes, en general, que las declaraciones en línea en los RDBMS modernos?[duplicar]

StackOverflow https://stackoverflow.com/questions/59880

  •  09-06-2019
  •  | 
  •  

Pregunta

Esta pregunta ya tiene respuesta aquí:

La sabiduría convencional afirma que los procedimientos almacenados son siempre más rápidos.Entonces, como siempre son más rápidos, úsalos. TODO EL TIEMPO.

Estoy bastante seguro de que esto se basa en algún contexto histórico en el que alguna vez fue así.Ahora, no estoy defendiendo que los procedimientos almacenados no sean necesarios, pero quiero saber en qué casos los procedimientos almacenados son necesarios en bases de datos modernas como MySQL, SQL Server, Oracle o <Inserta_tu_DB_aquí>.¿Es excesivo tener TODO el acceso a través de procedimientos almacenados?

¿Fue útil?

Solución

NOTA que esta es una mirada general a los procedimientos almacenados no regulados a un DBMS específico.Algunos DBM (e incluso, diferentes versiones de los mismos DBM!) Pueden funcionar en contra de esto, por lo que querrá verificar con sus DBM de Target antes de asumir que todo esto todavía se mantiene.

He sido DBA de Sybase ASE, MySQL y SQL Server de forma intermitente desde hace casi una década (junto con el desarrollo de aplicaciones en C, PHP, PL/SQL, C#.NET y Ruby).Así que no tengo ningún interés particular en esta (a veces) guerra santa.

El beneficio de rendimiento histórico de los procesos almacenados generalmente ha sido el siguiente (sin ningún orden en particular):

  • SQL previamente analizado
  • Plan de ejecución de consultas pregenerado
  • Latencia de red reducida
  • Beneficios potenciales del caché

SQL previamente analizado -- beneficios similares a los compilados vs.código interpretado, excepto en un nivel muy micro.

¿Sigue siendo una ventaja? No es muy notable en absoluto en la CPU moderna, pero si envía una única declaración SQL que es MUY grande once mil millones de veces por segundo, la sobrecarga de análisis puede acumularse.

Plan de ejecución de consultas pregenerado.Si tiene muchos JOIN, las permutaciones pueden volverse bastante inmanejables (los optimizadores modernos tienen límites y cortes por razones de rendimiento).No es desconocido que SQL muy complicado tenga latencias distintas y medibles (he visto una consulta complicada que tarda más de 10 segundos en generar un plan, antes de modificar el DBMS) debido a que el optimizador intenta encontrar el "mejor valor cercano". " plan de ejecución.Los procedimientos almacenados, generalmente, almacenarán esto en la memoria para que pueda evitar esta sobrecarga.

¿Sigue siendo una ventaja? La mayoría de los DBMS (las últimas ediciones) almacenarán en caché los planes de consulta para declaraciones SQL INDIVIDUALES, lo que reduce en gran medida el diferencial de rendimiento entre los procesos almacenados y el SQL ad hoc.Hay algunas advertencias y casos en los que este no es el caso, por lo que deberá realizar pruebas en su DBMS de destino.

Además, cada vez más DBMS le permiten proporcionar planes de ruta del optimizador (planes de consulta abstractos) para reducir significativamente el tiempo de optimización (¡tanto para SQL ad hoc como para procedimientos almacenados!).

ADVERTENCIA Los planes de consultas en caché no son una panacea para el rendimiento.En ocasiones, el plan de consulta que se genera no es óptimo.Por ejemplo, si envías SELECT * FROM table WHERE id BETWEEN 1 AND 99999999, el DBMS puede seleccionar un escaneo completo en lugar de un escaneo índice porque está tomando cada fila de la tabla (así que diga las estadísticas).Si esta es la versión en caché, entonces puede obtener un bajo rendimiento cuando luego envía SELECT * FROM table WHERE id BETWEEN 1 AND 2.El razonamiento detrás de esto está fuera del alcance de esta publicación, pero para leer más, ver: http://www.microsoft.com/technet/prodtechnol/sql/2005/frcqupln.mspxy http://msdn.microsoft.com/en-us/library/ms181055.aspxy http://www.simple-talk.com/sql/performance/execution-plan-basics/

"En resumen, determinaron que el suministro de algo más que los valores comunes cuando se realizó una compilación o recompilación se realizó en la compilación del optimizador y almacenando en caché el plan de consulta para ese valor en particular.Sin embargo, cuando ese plan de consulta se reutilizó para las ejecuciones posteriores de la misma consulta para los valores comunes ('m', 'r' o 't'), resultó en un rendimiento subóptimo.Este problema de rendimiento subóptimo existió hasta que la consulta fue recompilada.En ese momento, según el valor del parámetro @P1 suministrado, la consulta podría o no tener un problema de rendimiento ".

Latencia de red reducidaR) Si está ejecutando el mismo SQL una y otra vez, y el SQL suma muchos KB de código, reemplazarlo con una simple "barra ejecutiva" realmente puede sumar.B) Los procesos almacenados se pueden utilizar para mover código de procedimiento al DBMS.Esto ahorra tener que enviar grandes cantidades de datos al cliente sólo para que éste envíe un poco de información (¡o ninguna en absoluto!).Análogo a hacer un JOIN en el DBMS vs.en tu código (¡el WTF favorito de todos!)

¿Sigue siendo una ventaja?R) La Ethernet moderna de 1 Gb (¡y de 10 Gb y más!) realmente hace que esto sea insignificante.B) Depende de qué tan saturada esté su red: ¿por qué transferir varios megabytes de datos de un lado a otro sin una buena razón?

Beneficios potenciales del cachéRealizar transformaciones de datos del lado del servidor puede ser potencialmente más rápido si tiene suficiente memoria en el DBMS y los datos que necesita están en la memoria del servidor.

¿Sigue siendo una ventaja?A menos que su aplicación tenga acceso a memoria compartida para los datos DBMS, la ventaja siempre será para los procesos almacenados.

Por supuesto, ninguna discusión sobre la optimización de procedimientos almacenados estaría completa sin una discusión sobre SQL parametrizado y ad hoc.

SQL parametrizado/preparado
Una especie de cruce entre procedimientos almacenados y SQL ad hoc, son sentencias SQL integradas en un lenguaje anfitrión que utiliza "parámetros" para los valores de consulta, por ejemplo:

SELECT .. FROM yourtable WHERE foo = ? AND bar = ?

Estos proporcionan una versión más generalizada de una consulta que los optimizadores modernos pueden usar para almacenar en caché (y reutilizar) el plan de ejecución de la consulta, lo que genera gran parte del beneficio de rendimiento de los procedimientos almacenados.

SQL ad hocSimplemente abra una ventana de consola en su DBMS y escriba una declaración SQL.En el pasado, estos eran los de "peor" rendimiento (en promedio), ya que el DBMS no tenía forma de optimizar previamente las consultas como en el método de proceso parametrizado/almacenado.

¿Sigue siendo una desventaja?No necesariamente.La mayoría de los DBMS tienen la capacidad de "abstraer" SQL ad hoc en versiones parametrizadas, negando así más o menos la diferencia entre los dos.Algunos hacen esto implícitamente o deben habilitarse con una configuración de comando (servidor SQL: http://msdn.microsoft.com/en-us/library/ms175037.aspx , Oráculo: http://www.praetoriate.com/oracle_tips_cursor_sharing.htm).

¿Lecciones aprendidas?La ley de Moore continúa avanzando y los optimizadores de DBMS, con cada lanzamiento, se vuelven más sofisticados.Claro, puede colocar cada pequeña y tonta declaración SQL dentro de un proceso almacenado, pero sepa que los programadores que trabajan en optimizadores son muy inteligentes y buscan continuamente formas de mejorar el rendimiento.Con el tiempo (si aún no está aquí), el rendimiento de SQL ad hoc será indistinguible (¡en promedio!) del rendimiento de los procedimientos almacenados, por lo que cualquier tipo de masivo El uso de procedimientos almacenados ** únicamente por "razones de rendimiento" ** me parece una optimización prematura.

De todos modos, creo que si evita los casos extremos y tiene un SQL bastante básico, no notará la diferencia entre los procedimientos ad hoc y almacenados.

Otros consejos

Razones para utilizar procedimientos almacenados:

  • Reducir el tráfico de la red - tienes que enviar la declaración SQL a través de la red.Con sprocs, puede ejecutar SQL en lotes, lo que también es más eficiente.
  • Plan de consultas de almacenamiento en caché -- la primera vez que se ejecuta el sproc, SQL Server crea un plan de ejecución, que se almacena en caché para su reutilización.Esto es particularmente eficaz para consultas pequeñas que se ejecutan con frecuencia.
  • Capacidad para utilizar parámetros de salida. - si envía SQL en línea que devuelve una fila, solo podrá recuperar un conjunto de registros.Con sprocs puedes recuperarlos como parámetros de salida, lo cual es considerablemente más rápido.
  • Permisos -- cuando envía SQL en línea, debe otorgar permisos sobre las tablas al usuario, lo que otorga mucho más acceso que simplemente otorgar permiso para ejecutar un sproc
  • Separación de lógica - eliminar el código generador de SQL y segregarlo en la base de datos.
  • Posibilidad de editar sin recompilar -- esto puede ser controvertido.Puede editar el SQL en un sproc sin tener que volver a compilar la aplicación.
  • Encuentra dónde se utiliza una tabla -- con sprocs, si desea encontrar todas las declaraciones SQL que hacen referencia a una tabla en particular, puede exportar el código sproc y buscarlo.Esto es mucho más fácil que intentar encontrarlo en el código.
  • Mejoramiento -- Es más fácil para un DBA optimizar el SQL y ajustar la base de datos cuando se utilizan sprocs.Es más fácil encontrar índices faltantes y demás.
  • Ataques de inyección SQL - SQL en línea correctamente escrito puede defenderse contra ataques, pero los sprocs son mejores para esta protección.

En muchos casos, los procedimientos almacenados son en realidad más lentos porque están más generalizados.Si bien los procedimientos almacenados se pueden ajustar mucho, en mi experiencia hay suficiente fricción institucional y de desarrollo como para que se dejen en su lugar una vez que funcionan, por lo que los procedimientos almacenados a menudo tienden a devolver muchas columnas "por si acaso", porque no es así. desea implementar un nuevo procedimiento almacenado cada vez que cambia su aplicación.Un OR/M, por otro lado, solo solicita las columnas que utiliza la aplicación, lo que reduce el tráfico de red, uniones innecesarias, etc.

Es un debate que sigue y sigue (por ejemplo, aquí).

Es tan fácil escribir procedimientos almacenados incorrectos como escribir una lógica de acceso a datos incorrecta en su aplicación.

Mi preferencia son los procesos almacenados, pero eso se debe a que normalmente trabajo con aplicaciones muy grandes y complejas en un entorno empresarial donde hay administradores de bases de datos dedicados que son responsables de mantener los servidores de bases de datos funcionando sin problemas.

En otras situaciones, estoy bastante contento con que las tecnologías de acceso a datos como LINQ se encarguen de la optimización.

Sin embargo, el rendimiento puro no es la única consideración.Aspectos como la seguridad y la gestión de la configuración suelen ser al menos igual de importantes.

Editar:Si bien el artículo de Frans Bouma es realmente detallado, se equivoca por mucho en lo que respecta a la seguridad.El hecho de que tenga 5 años tampoco ayuda a su relevancia.

No existe una diferencia de velocidad notable entre los procedimientos almacenados y las consultas preparadas o parametrizadas en la mayoría de las bases de datos modernas, porque la base de datos también almacenará en caché los planes de ejecución para esas consultas.

Tenga en cuenta que una consulta parametrizada no es lo mismo que sql ad hoc.

La razón principal por la que en mi opinión sigo favoreciendo los procedimientos almacenados hoy en día tiene más que ver con la seguridad.Si utiliza procedimientos almacenados exclusivamente, puede deshabilitar los permisos INSERTAR, SELECCIONAR, ACTUALIZAR, ELIMINAR, ALTERAR, SOLTAR, CREAR, etc. para el usuario de su aplicación, dejándolo solo con EJECUTAR.

Esto proporciona un poco de protección adicional contra 2do orden inyección SQL.Las consultas parametrizadas sólo protegen contra 1er pedido inyección.

Obviamente, el desempeño real debe medirse en casos individuales, no asumirse.Pero incluso en los casos en que el rendimiento es obstaculizado mediante un procedimiento almacenado, existen buenas razones para usarlos:

  1. Los desarrolladores de aplicaciones no siempre son los mejores codificadores de SQL.Los procedimientos almacenados ocultan SQL de la aplicación.

  2. Los procedimientos almacenados utilizan automáticamente variables de vinculación.Los desarrolladores de aplicaciones a menudo evitan las variables de vinculación porque parecen código innecesario y muestran pocos beneficios en sistemas de prueba pequeños.Más adelante, no utilizar variables de vinculación puede afectar el rendimiento del RDBMS.

  3. Los procedimientos almacenados crean una capa de indirección que podría resultar útil más adelante.Es posible cambiar los detalles de implementación (incluida la estructura de la tabla) en el lado de la base de datos sin tocar el código de la aplicación.

  4. El ejercicio de crear procedimientos almacenados puede resultar útil para documentar todas las interacciones de la base de datos de un sistema.Y es más fácil actualizar la documentación cuando las cosas cambian.

Dicho esto, normalmente incluyo SQL sin formato en mis aplicaciones para poder controlarlo yo mismo.Depende de su equipo de desarrollo y su filosofía.

El único tema que nadie ha mencionado todavía como beneficio de los procedimientos almacenados es la seguridad.Si crea la aplicación exclusivamente con acceso a datos a través de procedimientos almacenados, puede bloquear la base de datos para que el ÚNICO acceso sea a través de esos procedimientos almacenados.Por lo tanto, incluso si alguien obtiene un ID y una contraseña de base de datos, estará limitado en lo que puede ver o hacer en esa base de datos.

En 2007 estaba en un proyecto en el que usábamos MS SQL Server a través de un ORM.Teníamos 2 tablas grandes y en crecimiento que requerían entre 7 y 8 segundos de tiempo de carga en SQL Server.Después de crear dos procedimientos SQL almacenados grandes y optimizarlos desde el planificador de consultas, el tiempo de carga de cada base de datos se redujo a menos de 20 milisegundos, por lo que claramente todavía existen razones de eficiencia para usar procedimientos SQL almacenados.

Dicho esto, descubrimos que el beneficio más importante de los procedimientos almacenados era la mayor facilidad de mantenimiento, seguridad, integridad de los datos y desacoplamiento de la lógica empresarial de la lógica del middleware, beneficiando toda la lógica del middleware a partir de la reutilización de los 2 procedimientos. .

Nuestro proveedor de ORM hizo la afirmación habitual de que ejecutar muchas consultas SQL pequeñas iba a ser más eficiente que recuperar conjuntos de datos grandes y unidos.Nuestra experiencia (para nuestra sorpresa) mostró algo más.

Por supuesto, esto puede variar entre máquinas, redes, sistemas operativos, servidores SQL, marcos de aplicaciones, marcos ORM e implementaciones de lenguaje, así que mida cualquier beneficio que CREA que puede obtener al hacer otra cosa.

No fue hasta que hicimos una evaluación comparativa que descubrimos que el problema estaba entre el ORM y la base de datos que asumía toda la carga.

Prefiero usar SP cuando tiene sentido usarlos.De todos modos, en SQL Server no hay ninguna ventaja de rendimiento para los SP sobre una consulta parametrizada.

Sin embargo, en mi trabajo actual, mi jefe mencionó que nos vemos obligados a utilizar SP porque nuestros clientes los requieren.Sienten que están más seguros.No he estado aquí el tiempo suficiente para ver si estamos implementando seguridad basada en roles, pero tengo la sensación de que sí.

Por tanto, en este caso los sentimientos del cliente prevalecen sobre todos los demás argumentos.

Para mí, una ventaja de los procedimientos almacenados es que son independientes del idioma anfitrión:puedes cambiar de una aplicación C, Python, PHP o cualquier aplicación a otro lenguaje de programación sin tener que volver a escribir tu código.Además, algunas funciones, como las operaciones masivas, mejoran realmente el rendimiento y no están fácilmente disponibles (¿en absoluto?) en los idiomas anfitriones.

Lea el libro de Frans Bouma. excelente publicación (aunque un poco parcial) sobre eso.

Todo lo que puedo hablar es el servidor SQL.En esa plataforma, los procedimientos almacenados son encantadores porque el servidor almacena el plan de ejecución, lo que en la mayoría de los casos acelera bastante el rendimiento.Digo "en la mayoría de los casos", porque si el SP tiene rutas de ejecución muy variables, es posible que obtenga un rendimiento subóptimo.Sin embargo, incluso en esos casos, una refactorización inteligente de los SP puede acelerar las cosas.

Usar procedimientos almacenados para operaciones CRUD probablemente sea excesivo, pero dependerá de las herramientas que se utilicen y de sus propias preferencias (o requisitos).Prefiero SQL en línea, pero me aseguro de utilizar consultas parametrizadas para evitar ataques de inyección de SQL.Mantengo una huella de esto comic xkcd como recordatorio de lo que puede salir mal si no se tiene cuidado.

Los procedimientos almacenados pueden tener beneficios reales de rendimiento cuando se trabaja con varios conjuntos de datos para devolver un único conjunto de datos.Por lo general, es más eficiente procesar conjuntos de datos en el procedimiento almacenado que enviarlos por cable para que se procesen en el extremo del cliente.

Darse cuenta de esto está un poco fuera de tema de la pregunta, pero si está utilizando muchos procedimientos almacenados, asegúrese de que haya una manera consistente de ponerlos bajo algún tipo de control de fuente (por ejemplo, subversion o git) y poder migre actualizaciones desde su sistema de desarrollo al sistema de prueba al sistema de producción.

Cuando esto se hace a mano, sin forma de auditar fácilmente qué código está y dónde, rápidamente se convierte en una pesadilla.

No sé si son más rápidos.Me gusta usar ORM para acceder a datos (para no reinventar la rueda), pero me doy cuenta de que no siempre es una opción viable.

Frans Bouma tiene un buen artículo sobre este tema: http://weblogs.asp.net/fbouma/archive/2003/11/18/38178.aspx

Los procesos almacenados son excelentes para los casos en los que el código SQL se ejecuta con frecuencia porque la base de datos lo almacena tokenizado en la memoria.Si ejecutó repetidamente el mismo código fuera de un proceso almacenado, probablemente sufrirá un impacto en el rendimiento de la base de datos al analizar el mismo código una y otra vez.

Por lo general, llamo con frecuencia al código como un proceso almacenado o como un objeto SqlCommand (.NET) y lo ejecuto tantas veces como sea necesario.

Sí, son más rápidos la mayor parte del tiempo.La composición de SQL también es un área enorme para ajustar el rendimiento.Si estoy haciendo una aplicación de tipo back office, puedo omitirlas, pero cualquier cosa que tenga que ver con la producción, las uso con seguridad por todas las razones por las que otros también hablaron... es decir, seguridad.

EN MI HUMILDE OPINIÓN...

Restringir las operaciones "C_UD" a procedimientos almacenados puede mantener la lógica de integridad de los datos en un solo lugar.Esto también se puede hacer restringiendo las operaciones"C_UD" a una única capa intermedia.

Se pueden proporcionar operaciones de lectura a la aplicación para que puedan unir solo las tablas/columnas que necesitan.

También se pueden utilizar procedimientos almacenados en lugar de consultas parametrizadas (o consultas ad-hoc) para obtener otras ventajas:

  • Si necesita corregir algo (un orden de clasificación, etc.), no necesita volver a compilar su aplicación.
  • Puede denegar el acceso a todas las tablas para esa cuenta de usuario, otorgar acceso solo a los procedimientos almacenados y enrutar todo el acceso a través de procedimientos almacenados.De esta manera, puede tener una validación personalizada de todas las entradas mucho más flexible que las restricciones de la tabla.

Tráfico de red reducido: los SP son generalmente peores que el SQL dinámico.Debido a que las personas no crean un nuevo SP para cada selección, si necesita solo una columna, se le indicará que use el SP que tiene las columnas que necesita e ignore el resto.Obtenga una columna adicional y el menor uso de red que acababa de desaparecer.También tiende a tener mucho filtrado de clientes cuando se utiliza SP.

almacenamiento en caché: MS-SQL no los trata de manera diferente, no desde que MS-SQL 2000 fuera 7, pero no lo recuerdo.

permisos: no es un problema, ya que casi todo lo que hago es web o tengo algún nivel de aplicación intermedio que realiza todo el acceso a la base de datos.El único software con el que trabajo que tiene acceso directo del cliente a la base de datos son productos de terceros que están diseñados para que los usuarios tengan acceso directo y se basan en otorgar permisos a los usuarios.Y sí, ¡el modelo de seguridad de permisos de MS-SQL apesta!(todavía no he dedicado tiempo a 2008) Como parte final de esto, me gustaría ver una encuesta sobre cuántas personas todavía realizan programación directa cliente/servidor versus programación de servidor de aplicaciones intermedias y web;y si están realizando proyectos grandes, ¿por qué no hay ORM?

Separación: la gente se preguntaría por qué se coloca la lógica empresarial fuera del nivel medio.Además, si busca separar el código de manejo de datos, hay formas de hacerlo sin colocarlo en la base de datos.

Capacidad de edición: ¿De qué no tiene que preocuparse por las pruebas ni el control de versiones?Además, solo es un problema con el cliente/servidor, en el mundo web no hay problema.

Encuentre la tabla: solo si puede identificar el SP que la usa, seguirá con las herramientas del sistema de control de versiones, el agente de saqueo o Visual Studio para encontrarla.

Optimización: su DBA debería utilizar las herramientas de la base de datos para encontrar las consultas que necesitan optimización.La base de datos puede decirle al DBA qué declaraciones consumen más tiempo y recursos y pueden corregirlas desde allí.Para declaraciones SQL complejas, se debe indicar a los programadores que hablen con el DBA si las selecciones simples no se preocupan por eso.

Ataques de inyección SQL: SP no ofrece mejor protección.Lo único que reciben el visto bueno es que la mayoría de ellos enseñan el uso de parámetros versus SQL dinámico, la mayoría de los ejemplos ignoran los parámetros.

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