Como que solo se compila una vez?

Tengo un problema con el siguiente concepto,que espero me ayuden a resolver

Es acerca de una de las ventajas mas famosas de los procedimientos almacenados que dice asi:

"Una sentencia se compila cada vez que se ejecuta en la base de datos. En cambio, un procedimiento almacenado es compilado una sola vez y se crea un plan de ejecución que se usará cada vez que se hace una llamada al procedimiento almacenado. Se disminuye la carga del servidor."

Como es posible que se compile una sola vez? digo si lo llamo varias veces y los parametros que mando son diferentes como es posibles esto si tuviera los mismos parametros siempre,lo entendería pero la verdad es que cambian!!!

Alguien que me eche una manita por aqui y me lo explique de una manera simple,ya que quiero saber explicar bien cuando me pregunten!!!!

Gracias de antemano por sus comentarios!!!

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.

comportamiento de sql

Saludos, para responderte seria mejor que especificaras con que gestor de bd estas trabajando o quieres saber como se comporta ya que cada uno trabaja distinto, aunque por la definicion que das creo que es MS SQL SERVER.

la primera respuesta pues seria una analogia a las mismas funciones que usas al programar en un lenguaje, creas tu funcion la cual recibe parametros, tu solo la compilas una vez y la ejecutas todas las veces que quieras, lo mismo hace el gestor de bd, creas el procedimiento almacenado, realiza el analsis lexico y despues de otros pasos lo compila y lo deja preparado para su uso, es decir que ya no pasa por el proceso de analisis lexico y de procesamiento de la consulta, ya solo se ejecuta, todo esto es un proceso transparente.

Si quieres saber un poco mas sobre que pasa en MSSQL Server cuando ejecutas una consulta por ejemplo, te dejo esta liga, el proceso es practicamente el mismo que para un procedimiento almacenado, la unica diferencia es que una consulta normal no se guarda en el servidor y el procedimiento almacenado si.

Execution Plan Basics

y si quieres ir mas alla y entender mas a fondo el proceso de una consulta te recomiendo leer este libro

Inside Microsoft SQL Server 2008: T-SQL Querying
autor Itzik Ben-Gan

Por eso son

Por eso son parametros.

Imaginate un programa que sume dos números:

1 + 2

Si quisieras que sumara otros dos números no tendrías que hacer otro programa para

3 + 4

Bastaría con usar parametros para los numero a sumar:

parametro: a, b  de tipo número
a + b

El codigo que se compila es la "logica" para sumar dos números y esto se hace una sola vez.

En cambio, si se deja una sentencia dinámica, la compilación se hara n veces.

Es cierto que esta es una ventaja , pero es muy pequeña comparada con la gran desventaja que implica tener la lógica del negocio en StoredProcedures... o sea NO LO HAGAS. No uses stored procedures para obtener mayor desempeño hasta haber agotado las demás opciones ( optimizar la tabla, manejo de indices, guardar la información correcta, hacer las consultas correctas ) Es decir, se debe de recurrir a esta y otras optimizaciones, hasta que tenga una solución no optima funcionando correctamente.

Por ejemplo, al presentar un listado de alumnos, no se necesita toda la información de una sola vez, lo que se necesita es el id y el nombre para después poder presentar el detalle.

Entonces en vez de:

select * from alumnos;

Se debería de escribir:

select id, nombre from alumnos where  estatus = activo and fecha_inscripcion > blahbla

Otra forma de mejorar el rendimiento es con sentencias preparadas ( prepared statements ) varios manejadores de bases de datos, "parsean" la sentencia una sola vez y las demás simplemente la ejecutan con los nuevos parametros.

En resumen:

SQL escrito cada vez: No usar
Stored Procedures: No usar ( a menos que seas DBA experto y sea el último recurso )
Prerared statements: Si!!!

Saludos.

Imagen de beto.bateria

Stored Procedures

Si necesitas obtener un dato en especial, y para obtenerlo es necesario hacer varias consultas, actualizaciones, borrados, etc, mejor hazlo con un Stored Procedures, asi no tienes que estar mandando y recibiendo informacion de la app a la base de datos.

Imagen de The man

Tengo una duda

Gracias por su atencion primero que todo,la verdad eso de usar procedimientos almacenados esta sumamente discutido,he oido muchas personas decir que no les gusta usar procedimientos almacenados hasta que no les quede de otra,como a ti OscarRyz por otro lado he visto comentarios en otros foros de gente que defienden los procedimientos almacenados a toda costa pues les parecen sumamente optimos y disminuyen el trafico de red

pero bueno cada quien tendra sus opiniones validas

otra pregunta:

Si ejecuto el query a nivel de mi codigo digamos un query con Prerared statements el metodo se compilara solo una vez estamos de acuerdo por el como con ejemplo que me pusiste del 1+1,pero la consulta se tedra que realizar una o mas veces sobre el motor de base de datos dependiendo las veces que ejecutemos el metodo,la consulta se tendra que realizar N cantidad de veces sobre el motor de base de datos.

Alo que entiendo los procedimientos almacenados al estar almacenados en la misma base de datos se compilarian una vez y las demas veces se seguiria llamando el procedimiento ya compilado

Por favor corrigeme si me equivoco es que asi es como lo entiendo

Saludos!! y gracias

@beto.bateria No! mejor deja

@The man Si, así es, ( en términos generales, cada manejador tiene sus particularidades ) con un prepared statement lo que te ahorras es la fase de parseo, pero aún así se tiene que ejecutar siempre.

Lo mejor en muchos de estos casos es m-e-d-i-r.... Se puede suponer muchas cosas que si tal o cual es más o menos rápido que otro, pero si no se hace una medición no sirve de absolutamente nada optimizar en la parte equivocada.

Ejemplo. La mayor parte del tiempo se pierde en datos que viajan por el cable. Si la conexión entre la BD y el servidor es excelente ( hay quien tiene fibra optica y demás ) entonces el tiempo se pierde entre el servidor y el cliente. Luego entonces de poco o nada sirve que se ponga un SP o no si de todas formas el servidor le manda información innecesaria al cliente.

Otra cosa, en un SP que tuvimos hace un par de semanas que se tardaba 11 minutos, después de varias optimizaciones y demás bajó a 4. ( bastante ) pero solo hasta que se reconstruyeron los indices y se le dio mantenimiento a la base de datos bajo de 4 minutos a 2 segundos! ... se estaba optimizando en el lugar erroneo.

Y así hay muchos escenarios.

@beto.bateria No! mejor deja esa lógica en el servidor. Es mucho mejor y más fácil tener un enlace dedicado o una buena configuración de hardware entre la base de datos y el servidor, que dejar esa lógica en un stored procedure.

Si se necesita hacer varias consultas/actualizaciones y es una cosa muy tardada mejor será que se ejecute de forma asincrona. Di no a los stored procedures.

:D

Imagen de The man

OK,ya comprendo

Gracias por sus opinones OscarRyz y beto.bateria,simpre me gusta oir opiniones diferentes a las mias para hacer compartivas y es mejor si se trata de gente con años en este ambito!!!

Imagen de bferro

De diseño y de gusto: ¿dónde poner la lógica de negocio?

El uso, no uso o abuso de procedimientos almacenados es una discusión tan vieja como el Génesis.
Para no abundar en lo que ya abunda y así evitar polución en la red, dejo algunas ligas de StackOverflow:
Business logic:Database or Application Layer
Logic: Database or Application/2 (constraints check)
Business Logic in Database versus Code?

Imagen de beto.bateria

Que tal OscarRyz, tal vez

Que tal OscarRyz, tal vez tengas una mala experiencia con procedimientos almacenados o leiste algo relacionado con esto, ¿podrias dar tus puntos de vista?.

Mi punto de vista respecto a lo que mencione es que el programa que administra la base de datos esta orientado a manejar esos datos, por lo tanto es mas rapido, otra es que aunque tengas un enlace exageradamente rapido, es exageradamente lento si lo comparas con el trabajo de memoria-procesador.

Claro, lo que mencione no es una regla, es aplicable dependiendo de los requerimientos de la aplicacion.

Donde quieres cargar el peso de procesamiento?

Pues mas bien depende en donde necesites/quieras cargar el peso del procesamiento, por ejemplo. Es como decir que se tienen dos valores enteros que deben estar almacenados en la base de datos.

¿Donde haces la operacion de suma, en tu codigo o en la BD?

Donde actualmente estoy trabajando, esta desicion es crucial. por ejemplo, realizar consultas con joins es imposible debido al numero de informacion que se tiene en BD, por lo que se tienen que hacer consultas simples y de ese resultado otra consulta y asi.

En una ocacion se me pidio modificar un sistema que toda la logica la metieron en un SP por lo que solo lo invocaban y tan tan. El problema es que se detectó que el servidor de DB estaba en chinga mientras que el servidor de procesamiento estaba de hueva... eso hacia que otras aplicaciones que consultaran a DB tuvieran una latencia mayor y porsupuesto el desempeño era mucho menor.

No digo que siempre sea mala idea hacer operaciones dentro del SGBD pero si es cierto que se tiene que saber el impacto que se tiene cuando se haga en codigo o en el motor de la base