In MySQL, è più veloce per cancellare e quindi inserire o è più veloce di aggiornare righe esistenti?

StackOverflow https://stackoverflow.com/questions/4020240

  •  26-09-2019
  •  | 
  •  

Domanda

Prima di tutto, lasciatemi dire che sto usando il PHP framework Yii, quindi mi piacerebbe rimanere nel suo insieme definito di istruzione SQL, se possibile. So che probabilmente avrei potuto creare una grande affermazione lungo SQL che avrebbe fatto tutto, ma preferisco non andare lì.

OK, immaginare ho una tabella Utenti e un tavolo FavColors. Poi ho un modulo in cui gli utenti possono selezionare le loro preferenze di colore controllando uno o più caselle di controllo da una lunga lista di possibili colori.

Tali risultati sono memorizzati come più righe della tabella FavColors simili (id, user_id, color_id).

Ora immaginate che l'utente entra e cambia la loro preferenza di colore. In questo scenario, quale sarebbe il modo più efficace per ottenere le nuove preferenze di colore nel database?

Opzione 1:

  • una massa eliminare di tutte le righe in cui le partite user_id
  • poi fare un inserto di massa di tutte le nuove righe

Opzione 2:

  • passare attraverso ogni riga corrente per vedere cosa è cambiato, e aggiornare di conseguenza
  • Se più righe devono essere inserite, farlo.
  • Se le righe devono essere cancellati, farlo.

Mi piace l'opzione uno, perché richiede solo due dichiarazioni, ma qualcosa si sente solo sbagliato su eliminazione di una riga solo per potenzialmente rimesso quasi gli stessi dati esatti. C'è anche la questione di rendere l'ids auto-incremento a valori più elevati di più in fretta, e non so se questo dovrebbe essere evitato per quanto possibile.

L'opzione 2 richiederà un lavoro molto di più di programmazione, ma impedirebbe situazioni in cui mi piacerebbe eliminare una riga solo per creare di nuovo. Tuttavia, l'aggiunta più carico in PHP non può valere la diminuzione del carico per MySQL.

Qualche idea? Cosa vorresti fare tutti?

È stato utile?

Soluzione

UPDATE è di gran lunga molto più veloce. Quando si UPDATE, i record della tabella sono solo di essere riscritti con nuovi dati. E tutto questo deve essere fatto di nuovo sul INSERT.

Quando si DELETE, gli indici devono essere aggiornati (ricordate, si elimina l'intera riga, non solo le colonne è necessario modificare) e blocchi di dati possono essere spostati (se si colpisce il limite PCTFREE). eliminazione Anche e l'aggiunta di nuovi ID modifiche record su auto_increment, quindi, se i record sono relazioni che sarebbe rotto, o avrebbero bisogno di aggiornamenti anche. Mi piacerebbe andare per UPDATE.

È per questo che si dovrebbe preferire INSERT ... ON DUPLICATE KEY UPDATE invece di REPLACE.

Il primo uno è un'operazione UPDATE in caso di una violazione di chiave, mentre il secondo è quello DELETE / INSERT

UPDATE: Ecco un esempio INSERT INTO table (a,b,c) VALUES (1,2,3) ON DUPLICATE KEY UPDATE c=c+1;

Per maggiori dettagli leggere aggiornamento documentazione

Altri suggerimenti

Philip, Hai provato a fare dichiarazioni preparate? Con le istruzioni preparate è possibile interrogare un unico lotto con parametri diversi e chiamarlo più volte. Alla fine del ciclo, è possibile eseguire tutti con minima quantità di latenza di rete. Ho usato istruzioni preparate con PHP e funziona benissimo. Poco più confuso di java istruzioni preparate.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top