2012-04-26 12 views
7

Ho un gioco iphone turnbased online, con un sacco di giochi in esecuzione allo stesso tempo. Sono in procinto di ottimizzare il codice, poiché sia ​​io che il server sono andati in crash oggi.1.3M query/ora. Come costruiresti le domande?

Questa è la configurazione:

In questo momento ho una tabella, "incontri" (70 campi di dati per ogni riga della struttura.), Che tengono traccia di tutte le partite attive. Ogni 7 secondi, l'iPhone si connetterà, scaricherà tutte le partite nella tabella "partite" in cui è attivo e aggiornerà l'interfaccia utente nell'iPhone.

Questo ha funzionato bene fino a circa 1.000 persone hanno scaricato il gioco e giocato. Il server si è bloccato.

Quindi per ottimizzare, immagino di poter creare una nuova tabella chiamata "matches_needs_update". Questa tabella ha 2 righe; nome e id. "Id" è uguale alla corrispondenza nella tabella "matches". Quando una partita viene aggiornata, viene inserita in questa tabella.

Ora, invece di cercare attraverso l'intera tabella "partite", la query controlla solo se il giocatore ha delle partite che devono essere aggiornate e quindi ottiene quelle partite dalla tabella "partite".

La mia domanda è duplice:

  1. E 'questa la soluzione ottimale?
  2. Se un giocatore è attivo, ad esempio 10 partite, c'è un buon modo per ottenere quelle 10 corrispondenze dalla tabella "partite" allo stesso tempo, o ho bisogno di un ciclo for facendo 10 query, una per ciascuna match:

    "SELECT * FROM matches WHERE id =?"

Grazie in anticipo

+6

Mentre il problema è serio, questo è uno dei migliori tipi di problemi che si possono avere, se ci pensate. Arrestarsi da troppi utenti effettivi è il miglior tipo di arresto anomalo. – Cyclone

+1

Una soluzione che utilizza le notifiche push potrebbe essere un modo migliore per aggirare il problema di prestazioni. In questo modo non avrai molti controlli a turno ridondanti –

+1

Sembra quasi che 1 persona possa essere attiva in più incontri e più persone possono essere attive in una partita? Sicuramente devi avere 3 tavoli? – DanRedux

risposta

6

suggerisco APC ...

... come sei in PHP, e presumo che stai facendo questo da un unico database mysql,

E 'facile da installare, e sarà predefinito da PHP 6 in poi.

Mantieni questa tabella 1 in memoria e volerà.

+0

Grazie per la risposta. Devo aggiornare tutto il mio codice php per gestirlo, o è solo per l'installazione? Grazie – BlackMouse

+0

APC è 2 cose. È una cache opcode (memorizza il codice PHP in modo che si carichi più rapidamente) e un archivio in memoria (vale a dire il valore-chiave). La prima parte avviene automaticamente e dà un aumento di velocità. Ma ti interessa il secondo bit. Quindi sì, è necessario aggiornare il codice. Leggi la pagina del manuale che ho collegato e inizia con apc_store per ottenere l'idea. – HappyTimeGopher

7

è necessario per ottenere dal database. Guarda su memcache o redis.

2

Il tuo database sembra davvero piccolo. Una tabella con 70 righe dovrebbe restituire entro millisecondi e anche centinaia di query al secondo dovrebbero funzionare senza problemi.

Un paio di puntatori tradizionali

  • Assicurati di piscina le connessioni. Non dovresti mai fare la connessione quando un cliente ha bisogno dei dati.
  • Assicurarsi che sia presente un indice su "l'utente è nella corrispondenza" in modo che il risultato venga recuperato dall'indice.
  • Sono sicuro che hai abbastanza memoria per contenere l'intera struttura nella cache e con queste piccole tabelle non dovrebbero essere necessarie ulteriori configurazioni.
  • Assicurarsi che lo schema sia normalizzato.Una tabella per ogni utente. Uno per ogni partita. E uno per ogni utente in una partita.
1

Il suo tempo per iniziare a memorizzare nella cache cose come ad esempio memcache e apc.

Per quanto riguarda il ciclo anche se le partite ... è il modo sbagliato per farlo.

In che modo un utente è connesso a una corrispondenza mediante una tabella xrif? o la tabella delle partite ha qualcosa come player1, player2.

Looping anche se le query non sono il modo per eseguire correttamente l'indicizzazione delle tabelle e fare un join per recuperare tutte le corrispondenze attive da un utente, sarebbe più efficiente. Date il numero di utenti che potreste desiderare (se non avete) suddividete i tavoli per i giochi attivi e inattivi.

Se ci sono 6000 giochi attivi e 3.000.000 di inattività, è estremamente vantaggioso suddividere queste tabelle.