Pregunta

Tengo una tabla que contiene información sobre las ciudades en un juego, puedes construir un edificio en cada turno y esto se registra con el valor "edificio usado".

Cada turno ejecutaré un script que altera usedBuilding a 0. La pregunta es, ¿cuál de las dos formas siguientes es más rápida? ¿Realmente importa cuál se use?

UPDATE cities SET usedBuilding = 0;
UPDATE cities SET usedBuilding = 0 WHERE usedBuilding = 1;
¿Fue útil?

Solución

En general, la cláusula del segundo caso (con la cláusula WHERE) sería más rápida, ya que no provocará una evaluación de activación, un registro de transacciones, una actualización de índice, etc.en las filas no utilizadas.

Potencialmente, dependiendo de la distribución de los valores 0/1, en realidad podría ser más rápido actualizar todas las filas en lugar de hacer la comparación, pero ese es un caso bastante degenerado.

Dado que aproximadamente el 95% de los costos de consulta son E/S, el uso de la cláusula WHERE no hará ninguna diferencia (ya que la columna no está indexada y usted está haciendo un escaneo de la tabla) o una gran diferencia (si la columna está indexada, o la mesa dividida, etc.).De cualquier manera, no duele.

Sospecho que para la cantidad de datos de la que estás hablando, no notarás una diferencia ni en los planes de ejecución ni en la velocidad, lo que lo hace académico en el mejor de los casos y, en el peor, una optimización prematura.Por lo tanto, recomendaría optar por lo que lógicamente tenga sentido para su aplicación.

Otros consejos

Si usedBuilding está indexado, será más rápido usar la cláusula donde, ya que solo accederá/actualizará las filas donde usedBuilding sea verdadero.Si no está indexado, estaría haciendo un escaneo completo de la tabla de todos modos, por lo que no haría mucha (¿alguna?) diferencia.

¡Pruebe ambas formas en un bucle unos miles de veces y cronometrelas!Probablemente dependa de:cuántos registros hay realmente en esta tabla y si todos caben en la memoria o deben paginarse en el disco.¿Cuántos edificios tienen el valor 1 antes de ejecutar la actualización (supongo que podría ser 1)?

No importa qué camino se use, pero el más corto probablemente sea el que menos pueda salir mal.El código que no escribes no puede tener errores.

¿Con qué frecuencia ocurren estos cambios?¿Cuántas filas esperas tener en esta tabla?Si las respuestas son "menos de una vez por segundo" y "menos de 10000", deja de preocuparte.

A menos que tengas algún tipo de interés académico en esto, por supuesto.

Parece que habría un menor número de transacciones para hacer que el "Conficio de las ciudades de actualización useBuilding = 0;" ejecutar que la consulta más específica.La razón principal que se me ocurre en contra de esto sería si tuviera más de un estado en su columna.Si es simplemente un valor booleano, entonces estaría bien, pero es posible que desees dedicar un tiempo a pensar si ese será siempre el caso.

La indexación también podría hacer que el plan de ejecución sea más eficiente utilizando la cláusula WHERE.

La mejor manera de obtener una respuesta definitiva sería realizar un perfil utilizando una gran cantidad de datos de muestra en diferentes escenarios.

la indexación no le ayudará en absoluto a menos que tenga algo así como el 2% de los valores usedBuilding = 1.

sin embargo, estas 2 declaraciones son lógicamente diferentes y pueden significar cosas totalmente diferentes.pero si para tu caso son iguales entonces usa el que no tiene la cláusula donde.

¿Cuántas filas tendrás exactamente?Sospecho que para un juego en línea más pequeño, realmente no te importa.

Si está realizando varias actualizaciones en la tabla "ciudades", podría ser una buena idea hacerlos todos en una declaración UPDATE si es posible.

Hacer cualquier cambio en una fila probablemente requiera tanta E/S como escribir la fila completa (excepto, por supuesto, actualizar las columnas indexadas también requiere escrituras de índice), por lo que pierde si realiza varias ACTUALIZACIONES que afectan a muchas filas.

Pero si tienes, digamos, <1000 filas, realmente no te importa :)

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