una - Función determinista en mysql
seleccionar el registro con el mayor valor en un campo sql (5)
Me confundí con un concepto aparentemente simple. Mysql define la función determinista como una función que
Siempre produce el mismo resultado para los mismos parámetros de entrada.
Así que en mi entendimiento, funciones como
CREATE FUNCTION foo (val INT) READS SQL DATA
BEGIN
DECLARE retval INT;
SET retval = (SELECT COUNT(*) FROM table_1 WHERE field_1 = val);
RETURN retval;
END;
no son deterministas (no hay garantía de que eliminar / actualizar / insertar no ocurra entre 2 llamadas a la función). Al mismo tiempo, vi muchas funciones que hacen más o menos lo mismo, es decir, devuelven un valor basado en el resultado de las consultas y se declaran como DETERMINISTIC
. Parece que me falta algo muy básico.
¿Alguien podría aclarar este tema?
Gracias.
Actualización Gracias por los que respondieron (+1); Hasta ahora parece que hay un mal uso generalizado de la palabra clave DETERMINISTIC
. Todavía es difícil de creer para mí que tanta gente lo haga, así que esperaré un poco por otras respuestas.
Creo que tu rutina es determinista. La documentación no es muy clara y esto ha llevado a muchas personas a estar muy confundidas acerca de este problema, que en realidad es más acerca de la replicación que cualquier otra cosa.
Considere una situación en la que haya configurado la replicación entre dos bases de datos. La base de datos maestra mantiene un registro de todas las rutinas almacenadas que se ejecutaron, incluidos sus parámetros de entrada, y envía este registro al esclavo. El esclavo ejecuta las mismas rutinas almacenadas en el mismo orden con los mismos parámetros de entrada. ¿La base de datos esclava ahora contendrá datos idénticos a la base de datos maestra? Si las rutinas almacenadas crean GUID y las almacenan en la base de datos, entonces no, las bases de datos maestra y esclava serán diferentes y la replicación se interrumpirá.
El propósito principal del indicador DETERMINISTIC es decirle a MySQL si incluir llamadas a esta rutina almacenada en el registro de replicación resultará en diferencias entre la base de datos maestra y los esclavos replicados, y por lo tanto no es seguro.
Cuando decida si el indicador DETERMINISTIC es apropiado para una rutina almacenada, piense de esta manera: si comienzo con dos bases de datos idénticas y ejecuto mi rutina en ambas bases de datos con los mismos parámetros de entrada, ¿mis bases de datos seguirán siendo idénticas? Si lo son entonces mi rutina es determinista.
Si declara que su rutina es determinista cuando no lo es, es posible que las réplicas de su base de datos principal no sean idénticas a las originales porque MySQL solo agregará la llamada de procedimiento al registro de replicación, y ejecutar el procedimiento en el esclavo no produce resultados idénticos .
Si su rutina no es determinista, MySQL debe incluir las filas afectadas en el registro de replicación. Si declara que su rutina no es determinista cuando no es así, no se romperá nada, pero el registro de replicación contendrá todas las filas afectadas cuando solo la llamada al procedimiento hubiera sido suficiente y esto podría afectar el rendimiento.
De la referencia de MySQL 5.0:
La evaluación de la naturaleza de una rutina se basa en la "honestidad" del creador: MySQL no comprueba que una rutina declarada DETERMINISTIC esté libre de declaraciones que produzcan resultados no deterministas. Sin embargo, una declaración incorrecta de una rutina puede afectar los resultados o afectar el rendimiento. Declarar una rutina no determinista como DETERMINISTA puede dar lugar a resultados inesperados al hacer que el optimizador tome decisiones de plan de ejecución incorrectas. Declarar una rutina determinista como NONDETERMINISTIC puede disminuir el rendimiento al provocar que no se usen las optimizaciones disponibles. Antes de MySQL 5.0.44, el optimizador acepta la característica DETERMINISTA, pero no la utiliza.
Entonces, ahí lo tiene, puede etiquetar una rutina almacenada como DETERMINISTIC
incluso si no lo está, pero puede dar lugar a resultados inesperados o problemas de rendimiento.
Determinista es importante si tiene la replicación activada o la puede usar algún día. Una llamada a una función no determinista que cause un cambio de fila (actualización o inserción), por ejemplo, tendrá que ser replicada usando un binario (basado en filas) donde una función determinista puede ser replicada. Esto se vuelve interesante cuando se miran los ejemplos de SQL anteriores, cuáles sucederán de la misma manera (darán el mismo resultado) cuando se repliquen utilizando la instrucción basada en la declaración, y cuáles se replicarán utilizando el resultado obtenido en el maestro (basado en filas). Si las instrucciones se ejecutan con el bloqueo apropiado y se puede garantizar que se ejecuten en el mismo orden en el Esclavo, entonces son deterministas. Si el orden de bloqueo / declaración que usa el Esclavo (sin concurrencia, el procesamiento en serie de las declaraciones en el orden en que se inician) significa que la respuesta puede ser diferente, entonces la función no debe ser determinista.
Los resultados DETERMINISTICOS no se refieren a diferentes conjuntos de resultados que se devuelven en diferentes momentos (dependiendo de los datos que se hayan agregado en el tiempo promedio). Además, es una referencia a los conjuntos de resultados en diferentes máquinas que utilizan los mismos datos. Si, por ejemplo, tiene 2 máquinas que ejecutan una función que incluye uuid () o que hace referencia a las variables del servidor, estas deben considerarse NO DETERMINISTRAS. Esto es útil, por ejemplo, en la replicación porque las llamadas de función se almacenan en el registro binario (maestro) y luego son ejecutadas por el esclavo. Para obtener detalles y ejemplos, visite http://dev.mysql.com/doc/refman/5.0/en/stored-programs-logging.html
El uso de DETERMINISTIC es, por lo tanto, correcto (99% del tiempo), por lo que no debe considerarse uso indebido.
No te estás perdiendo nada. Esta función no es determinista. Declararlo determinista no hará que la base de datos se derrita, pero podría afectar el rendimiento. Desde el sitio MySQL : "Declarar una rutina no determinista como DETERMINISTIC puede dar lugar a resultados inesperados al hacer que el optimizador tome decisiones incorrectas sobre el plan de ejecución". Pero MySQL no impone o verifica si su rutina determinista declarada es realmente determinista. MySQL confía en que usted sabe lo que está haciendo.