Che cosa significa esattamente che la memorizzazione di "grandi blob nel database riduce le prestazioni"?

8

Per qualcuno che conosce gli interni del database, questa può essere una domanda facile, ma qualcuno può spiegare in modo chiaro perché la memorizzazione di grandi blob (ad esempio film da 400 MB) nel database dovrebbe ridurre le prestazioni e cosa significa esattamente? Questa affermazione si trova spesso su Internet, ma non l'ho mai vista veramente spiegata.

Per essere precisi, mi riferisco alle prestazioni di SharePoint / MSSQL, ad esempio prestazioni di caricamento di file, esplorazione del sito, visualizzazione di elenchi, apertura di documenti ecc. - operazioni che si dice diventino più lente una volta che il database diventa troppo grande. L'esternalizzazione del blob al filesystem (che in SharePoint si chiama Remote Blob Storage, ovvero spostare i file fuori dal database, lasciando solo un riferimento) dovrebbe risolverlo in una certa misura, ma cosa esattamente - al livello inferiore - è la differenza? È ovvio che i backup richiederebbero più tempo con i file giganti memorizzati nel database ... ma quali sono le operazioni esattamente interessate e qual è il meccanismo sottostante (cioè in che modo i file memorizzati su un filesystem al di fuori del database sono accessibili o memorizzati diversamente)?

Supponiamo che una tabella semplice contenente colonne ID(guid, PK), FileName(string), Data(varbinary(max)) - una colonna Data di grandi dimensioni rallenti davvero le operazioni come la visualizzazione di un elenco di file su un sito Web (che presumo internamente significhi% run% co_de), o inserendo una nuova riga ? Non è come se le attuali colonne di contenuto binario siano indicizzate.

So che ci sono già state alcune domande come questa, ma non ho trovato una spiegazione adeguata.

    
posta w128 08.10.2013 - 13:28
fonte

4 risposte

9

Questo dipende molto dal sistema DB, ma una delle cose più importanti da considerare con i BLOB è l'elaborazione delle transazioni. Per esternalizzazione del filesystem, si prendono le modifiche ai dati binari dalle transazioni. Ciò si tradurrà in genere in operazioni write più veloci, contrarie alla situazione in cui il DB garantisce la conformità ACID con meccanismi di rollback completi ecc.

Le operazioni di lettura più lente possono anche verificarsi, quando si recuperano dati dal db da una tabella BLOB senza in realtà selezionando i dati BLOB, poiché il DB può memorizzare le restanti righe più localizzate su disco, che consentirà un accesso più veloce alla lettura (ma suppongo che la maggior parte dei moderni sistemi DB siano abbastanza intelligenti da memorizzare i dati binari effettivi in un'area del disco o in un tablespace separati, quindi senza testarlo con uno scenario reale non si dovrebbero fare ipotesi generali qui).

    
risposta data 08.10.2013 - 13:40
fonte
7

Di solito è un problema con la larghezza di banda. Se stai distribuendo centinaia di video all'ora, stai legando la larghezza di banda dentro e fuori dal database, principalmente copiando i buffer. È anche un problema se hai domande ingenue (probabilmente generate automaticamente da uno strumento ORM) che semplicemente selezionano tutte le colonne da una tabella. Sei anche soggetto alla frammentazione dei file come un filesystem (eccetto in questo caso la frammentazione dei record), ma (di solito) senza strumenti per de-frammentare. Se stai anche modificando il BLOB (ad esempio, stai supportando qualche tipo di modifica del video), il database copierà l'intero BLOB nel segmento di rollback o di ripetizione, quindi scriverà il BLOB aggiornato nel database. Quindi ora stai copiando quelle centinaia di megabyte e legando il segmento di ripetizione fino alla fine della transazione (per non parlare dei problemi che puoi incontrare se la dimensione del segmento di ripetizione è stata riparata).

    
risposta data 08.10.2013 - 17:21
fonte
6

Potrebbe essere utile esaminare SQL Server FileTables . L'idea è quella di fornire il meglio di entrambi i mondi: accesso e prestazioni a livello di file system, oltre all'accesso al database e alla sicurezza e ai servizi integrati. In alcuni casi il database ha una performance overhead. Basta confrontare un file HTML hard-coded su un server web con uno che deve recuperare il contenuto da un database.

Immagina che un'applicazione che non ha trovato la memorizzazione dei BLOB nel database costituisca un limite significativo alle prestazioni, ma poi l'app è cresciuta fino al punto in cui si trovava. C'è meno di un cambiamento di codice usando FileTables. Inoltre, è possibile gestire la transazione a livello di database e livello di file senza un sacco di codice. Il file e i metadati sono disponibili con SQL.

Sul server Windows, viene creata un'unità di condivisione per accedere ai file senza utilizzare la transazione di database.

È un problema comune che Microsoft ha tentato di gestire "senza problemi" con SQL Server 2012. Non è una funzionalità errata per giustificare un aggiornamento.

    
risposta data 08.10.2013 - 16:17
fonte
5

Per sapere perché questo è brutto, devi sapere come viene salvato un database sul disco rigido (in particolare le righe). Il contenuto fisico di una riga salvata sul disco è suddiviso nelle sue controparti statiche e dinamiche. Campi come int, byte, char (n) che hanno una lunghezza fissa sono elencati per primi. Quello che segue è un numero di lunghezza fissa che si riferisce al numero di campi di lunghezza variabile da seguire. Tutti i campi variabili (indipendentemente dall'ordine delle colonne presentate all'utente, il programmatore) vengono aggiunti alla fine, ciascuno con un numero di lunghezza fissa che determina la quantità di spazio occupata dal campo della lunghezza variabile.

Per darti un esempio concreto. Supponiamo che la mia tabella sia la seguente:

char(3) A
varchar(4) B
int C

Ora supponiamo che io faccia INSERT INTO mytable (A, B, C) VALUES ('AAA', 'B', 256) . Sul database, quella riga verrebbe probabilmente archiviata come segue:

IlcampoAvienesalvatocomecisiaspetterebbe.Seavessiinserito"A", avrebbe fornito un carattere speciale per contrassegnare la fine prematura della stringa dopo il primo carattere, ma occuperebbe lo stesso spazio.

Il campo C viene salvato come equivalente binario di 256. Perché C e non B? C è il prossimo campo statico con lunghezza fissa e, come tale, viene raggruppato insieme a tutti gli altri dati statici nella riga del database.

Il campo D è meta informazioni per il database che indica che nella seguente sezione di campi di lunghezza variabile, ci sarà precisamente 1 campo.

Il campo E è ancora una meta informazione per il database che indica che per questo particolare campo, ha una lunghezza massima di 1 carattere. Questa informazione è essenziale perché altrimenti il database non saprebbe dove finisce il campo B e inizia un altro campo di lunghezza variabile.

Tutto questo per dimostrare come i database gestiscono il salvataggio di campi a lunghezza variabile. BLOB è un campo a lunghezza variabile per questo effetto. La struttura del database consente a una riga di contenere sia valori piccoli che grandi nel BLOB, tuttavia, ci sono altri fattori in gioco qui. I database normalmente gestiscono blocchi di informazioni poiché ai dischi non interessa il contenuto, ma piuttosto se si inserisce in un singolo blocco.

Il database proverà ad adattare tutte le righe in un singolo blocco senza dover separare una riga in due parti, perché altrimenti l'effetto è lo stesso di avere un file frammentato sul disco rigido. Una volta caricato un chunk, se la riga supera quel particolare chunk, il disco rigido deve quindi cercare il resto in un altro blocco. Peggio ancora, non è possibile che un database sappia che una riga occupa più di un chunk senza leggerne completamente il contenuto poiché è di lunghezza variabile, quindi non è possibile ottimizzare recuperando entrambi i blocchi contemporaneamente.

Seguendo questa linea di logica, se si potesse creare un BLOB di lunghezza statica, non si avrebbe questo problema di ottimizzazione, poiché il database potrebbe semplicemente garantire che la dimensione del blocco sia maggiore della dimensione minima della riga, garantendo così che la maggior parte delle righe non dovrà essere diviso tra più blocchi. Ovviamente, i database non lo fanno perché significherebbe dedicare spazio prezioso quando probabilmente non ne avrai bisogno.

I BLOB vanno bene quando si tratta di importi relativamente piccoli, ma per file di grandi dimensioni come video e simili, una soluzione comune è semplicemente quella di salvare il percorso del file nel database e lasciare che il software si occupi di caricare il file che è quasi sempre più efficiente.

Spero che lo spieghi. :)

    
risposta data 08.10.2013 - 17:40
fonte