2010-09-16 15 views
6

Actualmente, he creado una página de Facebook que extrae notificaciones de diferentes tablas, digamos unas 8 tablas. Cada tabla tiene una estructura diferente con diferentes columnas, así que lo primero que se me ocurre es que tendré una tabla global, como una tabla de contenido, y la actualizaré con cada nuevo golpe. Sé que las inserciones son intensivas en recursos, pero esperaba que, dado que es una tabla estática, solo agregaría quizás un nuevo registro cada 100 visitantes, así que pensé "QUIZÁ" podría hacerlo, pero estaba equivocado. Me las arreglé para obtener bloqueos de solo tres personas martillando el sitio web.MySql Temp Tables VS Views VS arrays php

Así que de todos modos, ahora tengo que volver a hacerlo utilizando un método diferente. Inicialmente iba a hacer vistas, pero tengo un problema con las vistas. La tabla seleccionada deberá contener la identificación de un usuario. Aquí hay un ejemplo de una declaración de selección de php:

$get_events = " 

    SELECT id, " . $userId . ", 'admin_events', 0, event_start_time 
     FROM admin_events 
     WHERE CURDATE() < event_start_time AND 
       NOT EXISTS(SELECT id 
         FROM admin_event_registrations 
         WHERE user_id = " . $userId . " AND admin_events.id = event_id) AND 
       NOT EXISTS(SELECT id 
         FROM admin_event_declines 
         WHERE user_id = " . $userId . " AND admin_events.id = event_id) AND 
       event_capacity > (SELECT COUNT(*) FROM admin_event_registrations WHERE event_id = admin_events.id) 
      LIMIT 1 

Disculpe el desorden. En cualquier caso, como puede ver, necesito devolver el Id de usuario de la página como una columna seleccionada de la tabla. No pude entender cómo hacerlo con vistas, así que no creo que las vistas sean la forma en que me dirigiré porque hay muchas más de este tipo de consultas. Vengo de un fondo MSSQL, y me encantan los procedimientos almacenados, por lo que si hay procedimientos almacenados para MYSQL, sería excelente.

A continuación empecé a pensar en las tablas temporales. La mesa estará en la memoria, la mesa probablemente tendrá 150 filas como máximo y no habrá puntos muertos. ¿Sigue siendo muy costoso hacer inserciones en una mesa temporal? ¿Terminaré bloqueando el servidor? En este momento tenemos quizás 100 usuarios por día, pero quiero intentar ser una prueba de futuro cuando tengamos más usuarios.

Después de pensarlo mucho, me di cuenta de que la única forma es que el usuario php obtenga todos los resultados como una matriz. El problema es que me gustaría conseguir algo como:

$my_array[0]["date_created"] = <current_date> 

El problema con lo anterior es que tengo para ordenar por date_created, pero esto es una matriz multidimensional.

De todos modos, para obtener 150 a 200 registros MAX de una base de datos, ¿qué enfoque tomaría? Temp Table, View o php?

Respuesta

5

Algunos pensamientos:

tablas temporales: tablas temporales sólo durará el tiempo que la sesión está vivo. Si ejecuta el código en un script PHP, la tabla temporal se destruirá automáticamente cuando el script termine de ejecutarse.

Vistas: Estos son principalmente para ocultar la complejidad en que se crea con una combinación y luego se accede como una sola tabla. El código subrayado es una instrucción SELECT.

PHP Array: Un poco más engorroso que SQL para obtener datos. Sin embargo, PHP tiene algunas funciones para facilitar la vida pero no un lenguaje de consulta real.

procedimientos almacenados: Existen procedimientos almacenados en MySQL - ver: http://dev.mysql.com/doc/refman/5.0/en/stored-routines-syntax.html

Mi recomendación: En primer lugar, volver a escribir la consulta utilizando el Analizador de consultas de MySQL: http://www.mysql.com/products/enterprise/query.html

Ahora usaría PDO para poner mis valores en una matriz usando PHP. Esto aún dejará la carga inicial pesada en el motor DB y evitará que realice múltiples llamadas al servidor DB.

+0

Las vistas no son necesarias en las sentencias 'select'. También pueden ser tablas temporales. Ver http://www.percona.com/blog/2007/08/12/mysql-view-as-performance-troublemaker/, y http://www.percona.com/blog/2010/05/19/a -workaround-for-the-performance-problems-of-temptable-views /, y http://dba.stackexchange.com/a/16376/9405 – Pacerier

0

El problema es que está utilizando subconsultas correlacionadas. Me imagino que su consulta tardará un poco en ejecutarse si no está en el caché de consultas. Eso es lo que estaría causando que su tabla se bloquee y cause contención.

Cambiar el tipo de tabla a InnoDB ayudaría, pero su problema principal es su consulta.

150 a 200 registros es una cantidad muy grande. MySQL admite procedimientos almacenados, pero esto no es algo para lo que lo necesitaría. Las inserciones no requieren muchos recursos, pero muchas de ellas a la vez o en secuencia (uso de sintaxis de inserción masiva) pueden causar problemas.

+0

Sé que mi tabla es InnoDB. En algún momento podría haber una inserción masiva, dependiendo de la cantidad de notificaciones que tengo que actualizar, así que eso es probablemente lo que está sucediendo. – JohnathanKong

1

Prueba esto:

SELECT id, " . $userId . ", 'admin_events', 0, event_start_time 
    FROM admin_events AS ae 
    LEFT JOIN admin_event_registrations AS aer 
    ON ae.id = aer.event_id 
    LEFT JOIN admin_event_declines AS aed 
    ON ae.id = aed.event_id 
    WHERE aed.user_id = ". $userid ." 
    AND aer.user_id = ". $userid ." 
    AND aed.id IS NULL 
    AND aer.id IS NULL 
    AND CURDATE() < ae.event_start_time 
    AND ae.event_capacity > ( 
     SELECT SUM(IF(aer2.event_id IS NOT NULL, 1, 0)) 
     FROM admin_event_registrations aer2 
     JOIN admin_events AS ae2 
     ON aer2.event_id = ae2.id 
     WHERE aer2.user_id = ". $userid .") 
    LIMIT 1 

Todavía tiene una subconsulta, pero se puede encontrar que es mucho más rápido que las otras opciones que se ofrecen. MySQL puede unir tablas fácilmente (sin embargo, todas deberían ser del mismo tipo de tabla). Además, la última instrucción de recuento no responderá de la forma que desee con resultados nulos a menos que maneje valores nulos. Todo esto se puede hacer en un instante, y con las instrucciones de combinación debería reducir su tiempo de consulta global significativamente.

+0

Eso sería ideal, pero desafortunadamente todas las tablas tienen campos diferentes y no tienen enlaces entre sí. Recuerde que este es un sistema de notificación, por lo que muestra cosas como nuevos usuarios, notificaciones de administradores, eventos, referencias, etc. – JohnathanKong