2010-07-31 18 views

Respuesta

5

Parece como que estoy dando este consejo tres veces a la semana aquí en la SO, quizás debería renunciar y dejarlo ir :-) No, yo no lo creo:

Don' t usa funciones por fila en los cálculos de tu columna (o en las cláusulas order by) si quieres que tu base de datos se adapte bien. Debe verificar el rendimiento para su caso particular (medida , no adivinar) pero al hacer cálculos cuando lea, la base de datos generalmente afectará su capacidad de escalar (esto no importará en la libreta de direcciones pero las tiendas donde trabajo en tener cantidades enormes de datos).

El número de "¿cómo puedo obtener mi base de datos para ir más rápido?" las preguntas superan con creces la cantidad de "¿cómo uso menos espacio?" unos. Es un camino bien recorrido para sacrificar espacio en disco para el rendimiento.

El momento adecuado para hacer los cálculos es cuando cambian los datos. De esta forma, el costo de los cambios se amortiza en todas las lecturas.

Mi consejo es crear otra columna como dtLastAction para contener el valor de pedido a continuación, utilizar un desencadenador de inserción/actualización para establecerlo en el mismo que dtModified si no es nulo, o si dtPosteddtModified es nulo. Técnicamente, esto viola 3NF, pero está bien si sabes lo que estás haciendo, y los desencadenantes garantizan la consistencia de los datos en ese caso.

Luego indexe en la columna dtLastAction y vea cómo la velocidad de sus consultas mejora al (menor) costo de un trabajo adicional durante las inserciones y actualizaciones. Digo menos porque vasta mayoría de las tablas de la base de datos se leen con más frecuencia que las escritas (obviamente este método es inútil si su situación particular es una de las raras excepciones).

Por otra parte, para este caso particular, podría configurar dtModified y dtPosted al mismo valor al crear la entrada, lo que significa que dtModified nunca ser nulo. Aún puede detectar publicaciones que nunca se han modificado por el hecho de que estos dos valores de fecha y hora son idénticos.

+0

sí, creo que' dtLastAction' es genial. tal vez verificando si 'dtModified' es igual que' dtPosted' es aún mayor. No necesito 1 campo extra. tal vez renombrar 'dtModified' a' dtLastAction' lo hará más intuitivo –

+0

En general estoy de acuerdo con la reducción del costo de las lecturas. Sin embargo, este caso particular es tan simple que no creo que justifique toda la complejidad añadida del almacenamiento en caché. P.ej. si la acción se elimina, entonces debes actualizar la última fecha de acción para la última acción restante, ¡pesadilla! – malhal

13

puede utilizar COALESCE:

ORDER BY COALESCE(dtModified, dtPosted) 

Otra opción es utilizar la función específica de MySQL IFNULL en lugar de COALESCE.


Prueba de MySQL:

CREATE TABLE table1 (dtModified DATETIME NULL, dtPosted DATETIME NOT NULL); 
INSERT INTO table1 (dtModified, dtPosted) VALUES 
('2010-07-31 10:00:00', '2010-07-30 10:00:00'), 
(NULL     , '2010-07-31 09:00:00'), 
('2010-07-31 08:00:00', '2010-07-30 10:00:00'); 

SELECT dtModified, dtPosted 
FROM table1 
ORDER BY COALESCE(dtModified, dtPosted) 

Resultados:

dtModified   dtPosted 
2010-07-31 08:00:00 2010-07-30 10:00:00 
NULL     2010-07-31 09:00:00 
2010-07-31 10:00:00 2010-07-30 10:00:00 
+0

¿puedes usar un COALESCE en un ORDER BY? –

+0

Sí, creo que tienes que usar 'IFNULL' para MySQL. –

+0

@Daniel Vassallo: Acabo de probarlo en MySQL y parece funcionar bien. Vea mi respuesta actualizada para el SQL que utilicé. –

0

En el seleccionar, usar una instrucción CASE que toma el valor de la fecha de modificación, si no nula de lo contrario Fecha de publicación. Luego use esa nueva columna "calculada" para su ORDER BY.

Cuestiones relacionadas