2012-12-07 14 views
14

Durante la ricerca attraverso SO, ho trovato due risposte contraddittorie (e anche un commento che ha dichiarato che), ma nessuna risposta definitiva:memorizza TEXT/BLOB nella stessa tabella o no?

Il problema è: c'è qualche miglioramento delle prestazioni, se si memorizza un campo TEXT/BLOB fuori da un tavolo?

Noi assumiamo:

  • di selezionare correttamente (solo la selezione TESTO/BLOB se necessario, No Selezionare *)
  • tabelle sono indicizzati correttamente, in cui ha senso (quindi non è una questione di ' indicizzandolo ')
  • Il design del database non ha molta importanza. Questa è una domanda per identificare il comportamento di MySQL in questo caso speciale, non per risolvere alcuni problemi di progettazione del database. Supponiamo questo database ha un solo tavolo (o due, se il testo/BLOB si separa) motore
  • usato: InnoDB (altri sarebbero anche interessanti, se recuperare i risultati differenti)

Questo post stati, che mettendo TEXT/BLOB in una tabella separata, aiuta solo se stai già SELEZIONANDO in modo sbagliato (sempre SELEZIONA TESTO/BLOB anche quando non è necessario) - affermando sostanzialmente, che TEXT/BLOB nel la stessa tabella è fondamentalmente la soluzione migliore (meno complessità, nessun impatto sulle prestazioni, ecc.) dal momento che il TESTO/BLOB è memorizzato in modo sepratico in ogni caso

L'unica volta che spostare le colonne di TESTO in un'altra tabella offre vantaggi se si tende a selezionare solitamente tutte le colonne dalle tabelle. Questo è semplicemente l'introduzione di una seconda cattiva pratica per compensare il primo. Dovrebbe essere ovvio che i due torti non sono gli stessi di tre sinistri.

MySQL Table with TEXT column


Questo post tuttavia, afferma che:

Quando una tabella ha TEXT o BLOB colonne, la tabella non può essere memorizzato nella memoria

Significa che è già abbastanza per avere un TESTO/BLOB all'interno di un tavolo, per avere un impatto sulle prestazioni?

MySQL varchar(2000) vs text?


La mia domanda è sostanzialmente: Qual è la risposta giusta?

È davvero importante se si memorizza TEXT/BLOB in una tabella separata, se si SELECT correttamente?

Oppure ha anche un TESTO/UN BLOB all'interno di un tavolo, crea un potenziale impatto sulle prestazioni?

+1

Qualsiasi motore di archiviazione specifico che si sta utilizzando? InnoDB/MyISAM/NDB, ecc. – gertvdijk

+0

@gertvdijk L'ho aggiunto - Sono particolarmente interessato a una soluzione per InnoDB - ma fondamentalmente, se c'è una differenza, anche MyISAM e altri motori di archiviazione sarebbero interessanti – Katai

risposta

12

Se disponibile della versione di MySQL, utilizzare il formato di file InnoDB Barracuda utilizzando

innodb_file_format=barracuda 

nella configurazione di MySQL e impostare le vostre tabelle usando ROW_FORMAT=Dynamic (o Compressed) ad usarla.

In questo modo, InnoDB memorizzerà BLOB, TEXT e VARCHAR più grandi al di fuori delle pagine di riga, rendendoli molto più efficienti. Vedere this MySQLperformanceblog.com blog article per ulteriori informazioni.

Per quanto ho capito, l'utilizzo del formato Barracuda renderà la memorizzazione di TEXT/BLOB/VARCHAR in tabelle separate non più valide per motivi di prestazioni. Tuttavia, penso che sia sempre opportuno tenere a mente la corretta normalizzazione del database.

4

Un guadagno di prestazioni è avere una tabella con record di lunghezza fissa. Ciò significherebbe nessun campo di lunghezza variabile come varchar o text/blob. Con record a lunghezza fissa, MySQL non ha bisogno di "cercare" la fine di un record poiché conosce l'offset delle dimensioni. Sa anche quanta memoria ha bisogno di caricare i record X. Le tabelle con record a lunghezza fissa sono meno soggette alla frammentazione poiché lo spazio reso disponibile dai record eliminati può essere completamente riutilizzato. Le tabelle MyISAM hanno in realtà alcuni altri vantaggi dai record di lunghezza fissa.

Supponendo che si stia usando innodb_file_per_table, mantenere il tex/blob in una tabella separata aumenterà la probabilità che verrà utilizzata la memorizzazione nella cache del file system poiché la tabella sarà più piccola.

Detto questo, questa è una micro ottimizzazione. Ci sono molte altre cose che puoi fare per ottenere guadagni di prestazioni molto più grandi. Ad esempio, utilizzare unità SSD. Non ti darà abbastanza energia per spingere il giorno della resa dei conti quando i tuoi tavoli diventeranno così grandi che dovrai implementare il sharding.

Non si sente più parlare dei database utilizzando il "file system raw" anche se può essere molto più veloce. "Raw" è quando il database accede direttamente all'hardware del disco, ignorando qualsiasi file system. Penso che Oracle lo supporti ancora. Ma non vale la pena aggiungere la complessità, e devi sapere davvero cosa stai facendo. A mio parere, la memorizzazione del testo/blob in una tabella separata non vale la complessità aggiunta per il possibile guadagno di prestazioni. Hai davvero bisogno di sapere cosa stai facendo, e i tuoi schemi di accesso, per trarne vantaggio.

+0

Sì, ma cosa fa significa per un tavolo che in realtà ha un TESTO dentro di esso? Se MySQL memorizza il TEXT esternamente, in pratica dovrebbe essere solo un puntatore a quella memoria esterna, quindi dovrebbe essere pressoché lo stesso di memorizzare il TESTO in una tabella separata, manualmente. Questa è fondamentalmente la domanda, succede già automaticamente? (memorizzazione separata) Cosa sto cercando di scoprire, se non ha senso o meno, di farlo manualmente. Come viene gestito quel "riferimento" automatico al TEXT? – Katai

+0

C'è una differenza tra MySQL che memorizza il TEXT "esterno" e memorizza TEXT esternamente in un file separato. MySQL lo memorizza "esterno" all'interno del file, proprio come l'indice ei dati sono memorizzati nello stesso file con Innodb. Se lo si archivia in una tabella separata, si tratta di un file separato. Non è assurdo farlo manualmente, ma non si ottiene nemmeno un aumento delle prestazioni dell'1%. Non sarà nemmeno misurabile finché non avrai molti milioni di record. –

Problemi correlati