2010-09-16 28 views
6

Attualmente ho creato una pagina simile a Facebook che richiama le notifiche da tabelle diverse, diciamo circa 8 tabelle. Ogni tabella ha una struttura diversa con colonne diverse, quindi la prima cosa che mi viene in mente è che avrò una tabella globale, come un sommario, e la aggiornerò ad ogni nuovo hit. So che gli inserimenti sono a uso intensivo di risorse, ma speravo che dal momento che si tratta di un tavolo statico, aggiungerei solo un nuovo record ogni 100 visitatori, quindi ho pensato "FORSE" che avrei potuto farcela, ma ho sbagliato. Sono riuscito a ottenere deadlock da solo tre persone che martellano il sito web.MySql Temp Tables VS Views VS array php

Quindi, comunque, ora devo rifarlo usando un metodo diverso. Inizialmente stavo per fare punti di vista, ma ho un problema con le visualizzazioni. La tabella selezionata dovrà contenere l'id di un utente. Ecco un esempio di un'istruzione select da 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 

Mi dispiace per la confusione. In ogni caso, come puoi vedere, ho bisogno di restituire l'ID utente dalla pagina come colonna selezionata dalla tabella. Non riuscivo a capire come farlo con le visualizzazioni, quindi non penso che le visualizzazioni siano il modo in cui mi dirigerò perché ci sono molti più tipi di query. Vengo da uno sfondo MSSQL e adoro le stored procedure, quindi se ci sono stored procedure per MySQL, sarebbe eccellente.

Successivamente ho iniziato a pensare ai tavoli temporanei. La tabella sarà in memoria, la tabella avrà probabilmente un massimo di 150 righe e non ci saranno deadlock. È ancora molto costoso fare inserti su un tavolo temporaneo? Finirò per bloccare il server? Al momento abbiamo forse 100 utenti al giorno, ma voglio provare a essere a prova di futuro quando avremo più utenti.

Dopo un lungo pensiero, ho pensato che l'unico modo è l'utente php e ottenere tutti i risultati come una matrice. Il problema è che mi piacerebbe avere qualcosa di simile:

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

Il problema di quanto sopra è che devo ordinare in base date_created, ma questo è un array multi dimensionale.

In ogni caso, per trasferire da 150 a 200 record MAX da un database, quale approccio sceglieresti? Tabella Temp, vista o php?

risposta

5

Alcuni pensieri:

tabelle temporanee: tabelle temporanee durerà solo fino a quando la sessione è vivo. Se si esegue il codice in uno script PHP, la tabella temporanea verrà distrutta automaticamente al termine dell'esecuzione dello script.

Visualizzazioni: Questi sono principalmente per nascondere la complessità nel senso che si creano con un join e poi accedervi come una singola tabella. Il codice di sottolineatura è un'istruzione SELECT.

Array PHP: Un po 'più ingombrante di SQL per ottenere dati da. Tuttavia, PHP ha alcune funzioni per rendere la vita più semplice, ma nessun linguaggio di query reale.

stored procedure: ci sono stored procedure in MySQL - vedi: http://dev.mysql.com/doc/refman/5.0/en/stored-routines-syntax.html

La mia raccomandazione: In primo luogo, riscrivere la query utilizzando il MySQL Query Analyzer: http://www.mysql.com/products/enterprise/query.html

Ora userebbe PDO per mettere i miei valori in un array usando PHP. Ciò lascerà comunque il pesante sollevamento iniziale al motore DB e ti impedirà di effettuare più chiamate al server DB.

+0

Le viste non sono necessarie istruzioni 'select'. Potrebbero essere anche tavoli temporanei. Vedi http://www.percona.com/blog/2007/08/12/mysql-view-as-performance-troublemaker/ e http://www.percona.com/blog/2010/05/19/a -workaround-for-the-performance-problems-of-temptable-views /, e http://dba.stackexchange.com/a/16376/9405 – Pacerier

0

Il problema è che si stanno utilizzando sottoquery correlate. Immagino che la tua query richieda un po 'di tempo per essere eseguita se non si trova nella cache della query? Questo è ciò che potrebbe causare il blocco della tabella e causare conflitti.

È possibile modificare il tipo di tabella in InnoDB, ma il problema principale è la query.

Da 150 a 200 record è una quantità molto. MySQL supporta le stored procedure, ma questo non è qualcosa per cui ne avresti bisogno. Gli inserimenti non richiedono un uso intensivo delle risorse, ma molti di essi contemporaneamente o in sequenza (utilizza la sintassi di inserimento in blocco) possono causare problemi.

+0

So che il mio tavolo è InnoDB. Ad un certo punto potrebbe esserci un inserto di massa, a seconda del numero di notifiche che devo aggiornare, quindi è probabilmente quello che sta succedendo. – JohnathanKong

1

Prova questa:

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 

Ha ancora una sottoquery, ma troverete che è molto più veloce rispetto alle altre opzioni date. MySQL può unire facilmente le tabelle (dovrebbero essere tutte dello stesso tipo di tabella). Inoltre, l'ultima istruzione di conteggio non risponderà nel modo desiderato con risultati nulli a meno che non si gestiscano valori nulli. Tutto ciò può essere fatto in un lampo, e con le istruzioni di join dovrebbe ridurre significativamente il tempo di query complessivo.

+0

Sarebbe l'ideale, ma sfortunatamente tutte le tabelle hanno campi diversi e non hanno collegamenti tra loro. Ricorda che questo è un sistema di notifica, quindi mostra cose come nuovi utenti, notifiche da amministratori, eventi, referenze, ecc. – JohnathanKong