Database in grado di gestire> 500 milioni di righe

Sto cercando un database in grado di gestire (creare un indice su una colonna in un tempo ragionevole e fornire risultati per query selezionate in meno di 3 secondi) più di 500 milioni di righe. Postgresql o Msql su macchine di fascia bassa (CPU Core 6600, sistema 4 GB, 64 bit, Windows VISTA) gestiscono un numero così elevato di righe?

Aggiornamento: facendo questa domanda, sto cercando informazioni su quale database dovrei usare su una macchina di fascia bassa per fornire risultati per selezionare domande con uno o due campi specificati nella clausola where. Nessun join. Ho bisogno di creare indici – non ci possono volere secoli come su mysql – per ottenere prestazioni sufficienti per le mie query selezionate. Questa macchina è un PC di prova per eseguire un esperimento.

Lo schema della tabella:

create table mapper { key VARCHAR(1000), attr1 VARCHAR (100), attr1 INT, attr2 INT, value VARCHAR (2000), PRIMARY KEY (key), INDEX (attr1), INDEX (attr2) } 

MSSQL è in grado di gestire un numero così elevato di righe. Il tempo di query dipende completamente da molti più fattori rispetto al semplice conteggio delle righe.

Ad esempio, dipenderà da:

  1. quanti join fanno queste query
  2. quanto bene sono stati impostati i tuoi indici
  3. quanta ram è nella macchina
  4. velocità e numero di processori
  5. tipo e velocità del mandrino dei dischi rigidi
  6. dimensione della riga / quantità di dati restituiti nella query
  7. Interfaccia di rete velocità / latenza

È molto facile avere una tabella piccola (meno di 10.000 righe) che impiegherebbe un paio di minuti per eseguire una query. Ad esempio, utilizzando molti join, funzioni nella clausola where e indici zero su un processore Atom con 512 MB di RAM totale. 😉

Ci vuole un po ‘più di lavoro per assicurarsi che tutti gli indici e le relazioni con le chiavi esterne siano buoni, che le query siano ottimizzate per eliminare chiamate di funzioni inutili e restituire solo i dati effettivamente necessari. Inoltre, avrai bisogno di hardware veloce.

Tutto si riduce a quanti soldi vuoi spendere, alla qualità del team di sviluppo e alle dimensioni delle righe di dati con cui hai a che fare.

AGGIORNAMENTO Aggiornamento dovuto a cambiamenti nella domanda.

La quantità di informazioni qui non è ancora sufficiente per dare una risposta al mondo reale. Dovrai semplicemente testarlo e aggiustare il design del tuo database e l’hardware se necessario.

Ad esempio, potrei facilmente avere 1 miliardo di righe in una tabella su una macchina con quelle specifiche ed eseguire una query “select top (1) id from tableA (nolock)” e ottenere una risposta in millisecondi. Allo stesso modo, è ansible eseguire una query “select * from tablea” e ci vuole un po ‘perché, sebbene la query sia eseguita rapidamente, il trasferimento di tutti i dati attraverso il wire richiede un po’.

Il punto è che devi testare. Il che significa impostare il server, creare alcune delle tue tabelle e popolarle. Quindi devi passare attraverso l’ottimizzazione delle prestazioni per ottenere le tue query e gli indici giusti. Come parte del tuning delle prestazioni, scoprirai non solo come devono essere ristrutturate le query, ma anche quali parti della macchina potrebbero dover essere sostituite (ad esempio: disco, più ram, cpu, ecc.) In base alla serratura e aspetta i tipi.

Ti consiglio vivamente di assumere (o contrattare) uno o due DBA per farlo per te.

La maggior parte dei database è in grado di gestirli, riguarda ciò che si farà con questi dati e come lo si fa. Un sacco di RAM aiuterà.

Vorrei iniziare con PostgreSQL, è gratis e non ha limiti sulla RAM (a differenza di SQL Server Express) e nessun potenziale problema con le licenze (troppi processori, ecc.). Ma è anche il mio lavoro 🙂

Praticamente ogni database non stupido può gestire facilmente un miliardo di righe oggi. 500 milioni è fattibile anche su sistemi a 32 bit (anche se 64 bit aiuta davvero).

Il problema principale è:

  • Devi avere abbastanza RAM. Quanto è sufficiente dipende dalle tue domande.
  • È necessario disporre di un sottosistema di dischi sufficientemente buono. Questo significa praticamente se vuoi fare selezioni di grandi dimensioni, quindi un singolo piatto per ogni cosa è totalmente fuori questione. Sono necessari molti mandrini (o un SSD) per gestire il carico IO.

Sia Postgres che Mysql possono gestire facilmente 500 milioni di righe. Sull’hardware corretto

Quello che vuoi guardare è il limite di dimensioni del tavolo imposto dal software del database. Ad esempio, al momento della stesura di questo libro, MySQL InnoDB ha un limite di 64 TB per tabella , mentre PostgreSQL ha un limite di 32 TB per tabella ; né limita il numero di righe per tabella. Se correttamente configurati, questi sistemi di database non dovrebbero avere problemi nel gestire decine o centinaia di miliardi di righe (se ogni riga è abbastanza piccola), figuriamoci 500 milioni di righe.

Per una gestione ottimale delle prestazioni, è necessario disporre di spazio su disco sufficiente e buone prestazioni del disco, che è ansible ottenere con dischi in un RAID appropriato e grandi quantità di memoria accoppiato con un processore veloce (idealmente server-grade Processori Intel Xeon o AMD Opteron). Inutile dire che dovrai anche assicurarti che il tuo sistema di database sia configurato per prestazioni ottimali e che le tue tabelle siano indicizzate correttamente.

Il seguente articolo illustra l’importazione e l’uso di una tabella di 16 miliardi di righe in Microsoft SQL. http://sqlmag.com/t-sql/adventures-big-data-how-import-16-billion-rows-single-table .

Dall’articolo:

Ecco alcuni suggerimenti distillati dalla mia esperienza:

Maggiore è il numero di dati in una tabella con un indice cluster definito, più lento diventa l’importazione di record non ordinati. Ad un certo punto diventa troppo lento per essere pratico. Se si desidera esportare la tabella nel file più piccolo ansible, renderla in formato nativo. Ciò funziona meglio con le tabelle che contengono colonne per lo più numeriche perché sono rappresentate in modo più compatto nei campi binari rispetto ai dati dei caratteri. Se tutti i tuoi dati sono alfanumerici, non otterrai molto denaro esportandoli in formato nativo. Non consentire valori nulli nei campi numerici può ulteriormente compattare i dati. Se si consente che un campo sia annullabile, la rappresentazione binaria del campo conterrà un prefisso di 1 byte che indica quanti byte di dati seguiranno. Non è ansible utilizzare BCP per più di 2.147.483.647 record poiché la variabile contatore BCP è un numero intero a 4 byte. Non sono riuscito a trovare alcun riferimento a questo su MSDN o su Internet. Se la tua tabella comprende più di 2.147.483.647 record, dovrai esportarla in blocchi o scrivere la tua routine di esportazione. La definizione di un indice cluster su una tabella prepopolata richiede molto spazio su disco. Nel mio test, il mio log esplose fino a 10 volte la dimensione originale del tavolo prima del completamento. Quando si importa un numero elevato di record utilizzando l’istruzione BULK INSERT, includere il parametro BATCHSIZE e specificare il numero di record da impegnare alla volta. Se non si include questo parametro, l’intero file viene importato come una singola transazione, che richiede molto spazio di registrazione. Il modo più veloce per ottenere dati in una tabella con un indice cluster è di preselezionare prima i dati. È quindi ansible importarlo utilizzando l’istruzione BULK INSERT con il parametro ORDER.

Anche questo è piccolo rispetto al database Nasdaq OMX multi-petabyte, che ospita decine di petabyte (migliaia di terabyte) e migliaia di miliardi di righe su SQL Server.

Hai controllato Cassandra? http://cassandra.apache.org/

Come accennato, quasi tutti i DB oggi possono gestire questa situazione: ciò su cui si vuole concentrarsi è il sottosistema di I / O del disco. È necessario configurare una situazione RAID 0 o RAID 0 + 1 lanciando il maggior numero ansible di fusi al problema. Inoltre, dividere le unità logiche Log / Temp / Data per le prestazioni.

Ad esempio, supponiamo di avere 12 unità: nel controller RAID creerei 3 partizioni RAID 0 di 4 unità ciascuna. In Windows (diciamo) formatta ciascun gruppo come unità logica (G, H, I) – ora quando configuri SQLServer (diciamo) assegna il tempdb a G, i file di registro a H e i file di dati a I.

Non ho molto input su quale sia il miglior sistema da usare, ma forse questo suggerimento potrebbe aiutarti a ottenere un po ‘della velocità che stai cercando.

Se stai andando a fare corrispondenze esatte di stringhe varchar lunghe, specialmente quelle che sono più lunghe di quelle consentite per un indice, puoi fare una sorta di hash precalcolato:

 CREATE TABLE BigStrings ( BigStringID int identity(1,1) NOT NULL PRIMARY KEY CLUSTERED, Value varchar(6000) NOT NULL, Chk AS (CHECKSUM(Value)) ); CREATE NONCLUSTERED INDEX IX_BigStrings_Chk ON BigStrings(Chk); --Load 500 million rows in BigStrings DECLARE @S varchar(6000); SET @S = '6000-character-long string here'; -- nasty, slow table scan: SELECT * FROM BigStrings WHERE Value = @S -- super fast nonclustered seek followed by very fast clustered index range seek: SELECT * FROM BigStrings WHERE Value = @S AND Chk = CHECKSUM(@S) 

Questo non ti aiuterà se non stai facendo corrispondenze esatte, ma in tal caso potresti cercare nell’indicizzazione full-text. Questo cambierà davvero la velocità delle ricerche su una tabella di 500 milioni di righe.

Ho bisogno di creare indici (non ci vogliono secoli come su mysql) per ottenere prestazioni sufficienti per le mie query selezionate

Non sono sicuro di cosa intendi con “creare” indici. Normalmente è una cosa da fare una volta sola. Ora, è tipico quando si carica un’enorme quantità di dati come si potrebbe fare, per eliminare gli indici, caricare i dati e quindi aggiungere nuovamente gli indici, quindi il caricamento dei dati è molto veloce. Quindi, quando si apportano modifiche al database, gli indici vengono aggiornati, ma non è necessario che vengano creati ogni volta che viene eseguita la query.

Detto questo, i database hanno motori di ottimizzazione delle query in cui analizzeranno la tua query e determineranno il piano migliore per recuperare i dati, e vedranno come unire le tabelle (non rilevanti nel tuo scenario) e quali indici sono disponibili, ovviamente dovresti vuoi evitare una scansione completa della tabella, quindi l’ottimizzazione delle prestazioni e la revisione del piano di query sono importanti, come altri hanno già sottolineato.

Il punto sopra relativo a un checksum sembra interessante e potrebbe anche essere un indice su attr1 nella stessa tabella.