2011-04-08 26 views
7

Al ejecutar esta declaración de actualización se bloqueará cada fila de la tabla durante 5 segundos.Actualizar una tabla completa sin bloquear en MySQL

UPDATE `audio_clips` SET activity = activity * 0.95; 

¿Hay alguna manera de hacerlo en lotes (internamente a mysql), o para realizar la instrucción sin bloquear?

Este campo se usa para mostrar lo que actualmente es popular en el sitio (como Reddit, Hacker News, etc.). Cada vez que se reproduce un audio_clip, la actividad es golpeada por uno. De manera regular, 'decaemos' la actividad de cada clip. No me molesta actualizar de forma atómica, siempre y cuando cada fila se descomponga.

+0

¿El tipo de tabla es MyISAM o InnoDB? ¿Por qué estás actualizando todos los registros o es solo un error tipográfico? Te falta la cláusula WHERE en tu declaración SQL publicada. –

+0

InnoDB. Estoy actualizando cada registro porque ordenaré por la columna. Necesito artículos populares para subir en la lista, y artículos que ya no son populares para ir a la lista. – skattyadz

Respuesta

1

En última instancia, terminé haciéndolo en lotes. Puede que no sea perfectamente escalable, pero en lotes de 1000, cada registro está vinculado durante aproximadamente 35 ms. Todo el proceso solo toma 10 segundos de cada hora.

Lo suficientemente bueno.

4

Definitivamente tomaría un enfoque diferente.

¿No sería posible establecer una marca de tiempo a medida que se reproduce el clip, y al mismo tiempo calcular la disminución desde esa marca de tiempo? Al leer estadísticas, debe tomar la actividad menos la disminución desde la última marca de tiempo.

De esta forma, solo necesita una actualización por clip reproducido.

Para que sea concreto:

UPDATE `audio_clips` SET `lastview`=UNIX_TIMESTAMP(), 
        `activity`=1+`activity`*POW(0.9,(UNIX_TIMESTAMP()-`lastview`)/3600) 
       WHERE `clipid`=$clipid 

Para una descomposición de 10% por hora y una protuberancia de 1 por visión.

Para ver las estadísticas actuales:

SELECT *,`activity`*POW(0.9,(UNIX_TIMESTAMP()-`lastview`)/3600) AS `current_activity` 
     FROM `audio_clips` 
+0

Me gusta este enfoque, pero si planeo ordenar por la columna, aún tendría que hacer una disminución por lotes de clips inactivos, ¿o no? – skattyadz

+0

No, puede ordenar por cualquier expresión, también la actividad actual calculada. – mvds

+1

Hmm. Podría necesitar un almacenamiento en caché agresivo ya que no podría usar un índice. ¿Hace una diferencia si le digo que estamos hablando de ~ 350,000 filas? – skattyadz

Cuestiones relacionadas