Letture MySQL vs MongoDB 1000


321

Sono stato molto entusiasta di MongoDb e l'ho provato ultimamente. Avevo una tabella chiamata post in MySQL con circa 20 milioni di record indicizzati solo su un campo chiamato "id".

Volevo confrontare la velocità con MongoDB e ho eseguito un test per ottenere e stampare 15 record in modo casuale dai nostri enormi database. Ho eseguito la query circa 1.000 volte ciascuno per mysql e MongoDB e sono sorpreso di non notare molta differenza di velocità. Forse MongoDB è 1,1 volte più veloce. È molto deludente. C'è qualcosa che sto facendo di sbagliato? So che i miei test non sono perfetti ma MySQL è alla pari con MongoDb quando si tratta di leggere faccende intensive.


Nota:

  • Ho dual core + (2 thread) i7 cpu e ram da 4 GB
  • Ho 20 partizioni su MySQL ciascuna da 1 milione di dischi

Codice di esempio utilizzato per il test di MongoDB

<?php
function microtime_float()
{
    list($usec, $sec) = explode(" ", microtime());
    return ((float)$usec + (float)$sec);
}
$time_taken = 0;
$tries = 100;
// connect
$time_start = microtime_float();

for($i=1;$i<=$tries;$i++)
{
    $m = new Mongo();
    $db = $m->swalif;
    $cursor = $db->posts->find(array('id' => array('$in' => get_15_random_numbers())));
    foreach ($cursor as $obj)
    {
        //echo $obj["thread_title"] . "<br><Br>";
    }
}

$time_end = microtime_float();
$time_taken = $time_taken + ($time_end - $time_start);
echo $time_taken;

function get_15_random_numbers()
{
    $numbers = array();
    for($i=1;$i<=15;$i++)
    {
        $numbers[] = mt_rand(1, 20000000) ;

    }
    return $numbers;
}

?>


Codice di esempio per testare MySQL

<?php
function microtime_float()
{
    list($usec, $sec) = explode(" ", microtime());
    return ((float)$usec + (float)$sec);
}
$BASE_PATH = "../src/";
include_once($BASE_PATH  . "classes/forumdb.php");

$time_taken = 0;
$tries = 100;
$time_start = microtime_float();
for($i=1;$i<=$tries;$i++)
{
    $db = new AQLDatabase();
    $sql = "select * from posts_really_big where id in (".implode(',',get_15_random_numbers()).")";
    $result = $db->executeSQL($sql);
    while ($row = mysql_fetch_array($result) )
    {
        //echo $row["thread_title"] . "<br><Br>";
    }
}
$time_end = microtime_float();
$time_taken = $time_taken + ($time_end - $time_start);
echo $time_taken;

function get_15_random_numbers()
{
    $numbers = array();
    for($i=1;$i<=15;$i++)
    {
        $numbers[] = mt_rand(1, 20000000);

    }
    return $numbers;
}
?>

11
Quali sono i tempi attuali?
Abe Petrillo

30
Non sono un DBA, quindi questo è un commento non una risposta, ma la velocità non dovrebbe essere la considerazione principale nella scelta tra MySQL e MongoDB. Cose come lo schema o lo schema (ovvero la frequenza con cui lo schema dei dati deve cambiare) e il ridimensionamento delle dimensioni (ovvero quanto è facile condividere i dati in modo che una lettura tipica richieda dati da un solo server) sono più importanti per una scelta come questo.
Rossdavidh,

17
Come può essere più veloce nella lettura? Legge da un dispositivo meccanico. Come MySQL. Dipende dalla velocità del dispositivo stesso, non è possibile utilizzare una strana magia tramite il codice per superare i limiti dell'hardware.
NB

7
Questa domanda mi ricorda questo: mongodb-is-web-scale.com
oligofren

13
Le persone si sbagliano sul fatto che si sentono come se andassero l'uno o l'altro. Avrai bisogno di forno a microonde e forno nella tua cucina. Non puoi proprio dire che userò solo l'uno o l'altro. I casi d'uso per entrambi i sistemi sono diversi. Se hai bisogno di ACID per parte della tua app, usa RDBMS, se non ti preoccupi della coerenza e dei vincoli e le tue entità possono essere archiviate come tutte in una (raccolte), allora usa MongoDB. Finirai per usare un sistema ibrido, il punto chiave è decidere cosa memorizzare dove.
Teoman Shipahi

Risposte:


647

MongoDB non è magicamente più veloce. Se memorizzi gli stessi dati, organizzati sostanzialmente nello stesso modo e accedi esattamente allo stesso modo, non dovresti aspettarti che i tuoi risultati siano molto diversi. Dopotutto, MySQL e MongoDB sono entrambi GPL, quindi se Mongo avesse un codice IO magicamente migliore, allora il team MySQL potrebbe semplicemente incorporarlo nel loro codice.

Le persone vedono le prestazioni di MongoDB nel mondo reale in gran parte perché MongoDB consente di eseguire query in un modo diverso, più sensibile al carico di lavoro.

Ad esempio, si consideri un progetto che ha persistito molte informazioni su un'entità complicata in modo normalizzato. Ciò potrebbe facilmente utilizzare dozzine di tabelle in MySQL (o qualsiasi db relazionale) per archiviare i dati in forma normale, con molti indici necessari per garantire l'integrità relazionale tra le tabelle.

Ora considera lo stesso design con un archivio documenti. Se tutte queste tabelle correlate sono subordinate alla tabella principale (e spesso lo sono), allora potresti essere in grado di modellare i dati in modo che l'intera entità sia memorizzata in un singolo documento. In MongoDB puoi archiviarlo come un singolo documento, in una singola raccolta. È qui che MongoDB inizia a consentire prestazioni superiori.

In MongoDB, per recuperare l'intera entità, devi eseguire:

  • Una ricerca dell'indice sulla raccolta (presupponendo che l'entità sia recuperata dall'ID)
  • Recupera il contenuto di una pagina del database (il documento binario json effettivo)

Quindi una ricerca b-tree e una pagina binaria letta. Log (n) + 1 IO. Se gli indici possono risiedere interamente in memoria, quindi 1 IO.

In MySQL con 20 tabelle, devi eseguire:

  • Una ricerca indice nella tabella radice (di nuovo, supponendo che l'entità sia recuperata dall'id)
  • Con un indice cluster, possiamo supporre che i valori per la riga principale siano nell'indice
  • Oltre 20 ricerche di intervallo (si spera su un indice) per il valore pk dell'entità
  • Questi probabilmente non sono indici cluster, quindi le stesse ricerche di dati 20+ una volta che abbiamo capito quali sono le righe figlio appropriate.

Quindi il totale per mysql, anche supponendo che tutti gli indici siano in memoria (il che è più difficile poiché ce ne sono 20 volte di più) è di circa 20 ricerche di intervallo.

Queste ricerche di intervallo sono probabilmente composte da IO casuali: tabelle diverse risiederanno sicuramente in punti diversi sul disco ed è possibile che righe diverse nello stesso intervallo nella stessa tabella per un'entità possano non essere contigue (a seconda di come è stata l'entità aggiornato, ecc.).

Quindi, per questo esempio, il conteggio finale è circa 20 volte più IO con MySQL per accesso logico, rispetto a MongoDB.

Ecco come MongoDB può migliorare le prestazioni in alcuni casi d'uso .


43
e se mettessimo solo una tabella principale in mysql?
Ariso,

99
@ariso: questa è ottimizzazione mediante denormalizzazione. Può fornire un aumento delle prestazioni. Tuttavia, se lo fai, stai eliminando il tuo design pulito e tutta la potenza (per non parlare della maggior parte delle funzionalità) di un database relazionale. E funziona davvero solo fino a quando non raggiungi il limite della colonna.
Sean Reilly,

7
@SeanReilly Il tuo esempio con entità (dovrebbe essere modificato con oggetti, non esiste una programmazione orientata alle entità :)) non è valido. Come ha detto ariso, è possibile serializzare un oggetto e memorizzarlo nel db e deserializzarlo quando necessario (qualsiasi forma di serializzazione). Il vero potere degli oggetti persistenti è racchiuso in oodbms non in sistemi db documnet. Ma sono d'accordo sul fatto che ognuno ha i propri scopi e punti di forza (ma il tuo esempio offusca maggiormente la visione e la pertinenza di questo argomento).
Geo C.

9
20 join, direi, molto probabilmente non è la migliore query sul miglior schema di database che potrebbero essere.
Audrius Meskauskas,

8
@SeanReilly Ho trovato molto utile il tuo esempio. È possibile creare un'interfaccia speciale per MySQL che serializzi e deserializzi automaticamente gli oggetti sulle tabelle e si comporti come fa mongodb. Ma allora, perché non usare semplicemente qualcosa di specificamente progettato per essere usato in quel modo? Anche il tuo uso di "entità" ha senso. Il punto è che stai organizzando i dati come documenti anziché come campi in una tabella. Se il documento sia o meno un oggetto composto in un linguaggio OO è irrilevante per l'esempio.
BHS,

57

Hai concorrenza, ovvero utenti simultanei? Se esegui 1000 volte la query direttamente, con un solo thread, non ci sarà quasi alcuna differenza. Troppo facile per questi motori :)

MA ti consiglio vivamente di creare una vera sessione di test del carico, il che significa utilizzare un iniettore come JMeter con 10, 20 o 50 utenti ALLO STESSO TEMPO in modo da poter davvero vedere una differenza (prova a incorporare questo codice all'interno di una pagina Web JMeter potrebbe interrogare).

L'ho fatto oggi su un singolo server (e una semplice raccolta / tabella) e i risultati sono piuttosto interessanti e sorprendenti (MongoDb è stato molto più veloce in scrittura e lettura, rispetto al motore MyISAM e al motore InnoDb).

Questo dovrebbe davvero essere parte del tuo test: concorrenza e motore MySQL. Quindi, la progettazione di dati / schemi e le esigenze applicative sono ovviamente requisiti enormi, oltre i tempi di risposta. Fammi sapere quando ottieni risultati, ho anche bisogno di input su questo!


42
Puoi condividere i tuoi risultati?
Imran Omar Bukhsh

1
Sì, i risultati saranno molto utili
Vasil Popov,

3
Sicuramente questo sarebbe solo in scala ... se si trattasse di Mele alle Mele come hanno detto nel resto di questo argomento. Quindi se su avg esegue x, ora simula da più fonti, spiega perché mongo sarebbe più veloce. per esempio, diciamo solo per il gusto di dire che mysql era in avg più veloce per una singola richiesta ... perché mongo ora dovrebbe diventare più veloce per più? Non lo trovo molto scientifico. Sto dicendo che il test è valido .. ma non sono così sicuro su come la differenza sarebbe enorme se si confrontasse Mele e Mele come il resto dell'argomento spiega.
Seabizkit,

35

Fonte: https://github.com/webcaetano/mongo-mysql

10 file

mysql insert: 1702ms
mysql select: 11ms

mongo insert: 47ms
mongo select: 12ms

100 righe

mysql insert: 8171ms
mysql select: 10ms

mongo insert: 167ms
mongo select: 60ms

1000 file

mysql insert: 94813ms (1.58 minutes)
mysql select: 13ms

mongo insert: 1013ms
mongo select: 677ms

10.000 file

mysql insert: 924695ms (15.41 minutes)
mysql select: 144ms

mongo insert: 9956ms (9.95 seconds)
mongo select: 4539ms (4.539 seconds)

91
15 minuti per inserire 10.000 righe? È un database MySQL molto anemico. Nella mia esperienza, se tale operazione si avvicina a 1 secondo, il mio telefono si illumina con lamentele. :)
Mordechai,

1
Xtreme Biker dai un'occhiata al link. Ho pubblicato il test da altre persone con altre impostazioni.
user2081518

14
Alcuni punti: 1) Mysql deve essere ottimizzato e configurato correttamente, ci sono molti modi diversi per inserire grandi quantità di dati, e fatto correttamente può richiedere lo 0,1% dei 15 minuti, vedi ad esempio questa pagina . 2) MongoDB non scrive immediatamente i dati sul disco, motivo per cui "sembra" più veloce, ma se il computer si arresta in modo anomalo, i dati vengono persi. 3) La lettura è molto più veloce in MySQL
elipoultorak il

81
15min per 10.000 file? Hai digitato ogni riga? =))))
Iurie Manea

7
chiunque crede a un'affermazione secondo cui ci vogliono 1,7 secondi per inserire dieci file in mysql merita il dolore che provengono da mongo
John Haugeland

20

amico ,,, la risposta è che sostanzialmente stai testando PHP e non un database.

non preoccuparti di ripetere i risultati, commentando la stampa o meno. c'è un po 'di tempo.

   foreach ($cursor as $obj)
    {
        //echo $obj["thread_title"] . "<br><Br>";
    }

mentre l'altro pezzo viene speso tirando su un mucchio di numeri di Rand.

function get_15_random_numbers()
{
    $numbers = array();
    for($i=1;$i<=15;$i++)
    {
        $numbers[] = mt_rand(1, 20000000) ;

    }
    return $numbers;
}

poi c'è una grande differenza tra implode e dentro.

e infine cosa sta succedendo qui. sembra creare una connessione ogni volta, quindi testare il tempo di connessione più il tempo di query.

$m = new Mongo();

vs

$db = new AQLDatabase();

quindi il tuo 101% più veloce potrebbe rivelarsi più veloce del 1000% per la query sottostante spogliata del jazz.

urghhh.


4
naturalmente, la pratica del codice può fare una grande differenza in qualsiasi situazione, ma questo non è specifico per qualsiasi tipo di linguaggio, API o estensione. la generazione di numeri casuali prima di avviare il timer farà la differenza, ma la maggior parte del tempo all'interno del processo è senza dubbio dalle transazioni del database. la generazione di numeri casuali è banale, i database SQL e NoSQL non lo sono.
JSON,

1
non selezionare il numero di Rand. chiaramente hai perso la connessione di creazione ogni volta. tutti i problemi si sommano al test di qualcosa di diverso da quello previsto.
Gabe Rainbow,

2
No, non è mancato. MySQL non chiuderà la connessione fino al termine dello script, a meno che non venga chiamato mysqli_close (). Altrimenti, ripetere le chiamate a mysqli_connect () estrarrà solo la risorsa mysql esistente dalla tabella delle risorse corrente, anziché impegnarsi in una nuova procedura di connessione. Non sono esattamente sicuro di cosa sia l'oggetto AQLDatabase, ma se usa la libreria mysql (cosa che probabilmente fa) avrà lo stesso comportamento. L'estensione MongoDB utilizza il pool di connessioni, quindi la stessa cosa di base si verifica quando si crea una 'connessione' mongodb più di una volta in uno script.
JSON,

Sono d'accordo che il suo benchmark avrebbe potuto essere fatto diversamente, ma riflette gli stessi risultati di base di altri banchi MySQL vs Mongo che ho visto. Mongo è in genere più veloce durante l'inserimento (molto più veloce per inserimenti più semplici) e MySQL è in genere più veloce durante la selezione.
JSON,

certamente, ero troppo scontroso; è stata quella stringa HTML concat di "<br>" che mi ha davvero "esortato". non hai bisogno di una bella stampa nei test. anche iterando sembra un test php e non un test del database. nel complesso, quel momento "forse / forse" di AQLDatabase ... più ingredienti significa più incognite.
Gabe Rainbow,

17

https://github.com/reoxey/benchmark

prova delle prestazioni

confronto di velocità di MySQL e MongoDB in GOLANG1.6 e PHP5

sistema utilizzato per il benchmark: DELL cpu i5 4th gen 1.70Ghz * 4 ram 4GB GPU ram 2GB

Confronto della velocità tra RDBMS e NoSQL per INSERT, SELECT, UPDATE, DELETE eseguendo un numero diverso di righe 10.100,1000,10000,100000,1000000

La lingua utilizzata per eseguire è: PHP5 e la lingua più veloce di Google GO 1.6

________________________________________________
GOLANG with MySQL (engine = MyISAM)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
            INSERT
------------------------------------------------
num of rows             time taken
------------------------------------------------
10                      1.195444ms
100                     6.075053ms
1000                    47.439699ms
10000                   483.999809ms
100000                  4.707089053s
1000000                 49.067407174s


            SELECT
------------------------------------------------
num of rows             time taken
------------------------------------------------
1000000                 872.709µs


        SELECT & DISPLAY
------------------------------------------------
num of rows             time taken
------------------------------------------------
1000000                 20.717354746s


            UPDATE
------------------------------------------------
num of rows             time taken
------------------------------------------------
1000000                 2.309209968s
100000                  257.411502ms
10000                   26.73954ms
1000                    3.483926ms
100                     915.17µs
10                      650.166µs


            DELETE
------------------------------------------------
num of rows             time taken
------------------------------------------------
1000000                 6.065949ms
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^


________________________________________________
GOLANG with MongoDB
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
            INSERT
------------------------------------------------
num of rows             time taken
------------------------------------------------
10                      2.067094ms
100                     8.841597ms
1000                    106.491732ms
10000                   998.225023ms
100000                  8.98172825s
1000000                 1m 29.63203158s


            SELECT
------------------------------------------------
num of rows             time taken
------------------------------------------------
1000000                 5.251337439s


        FIND & DISPLAY (with index declared)
------------------------------------------------
num of rows             time taken
------------------------------------------------
1000000                 21.540603252s


            UPDATE
------------------------------------------------
num of rows             time taken
------------------------------------------------
1                       1.330954ms
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

________________________________________________
PHP5 with MySQL (engine = MyISAM)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
            INSERT
------------------------------------------------
num of rows             time taken
------------------------------------------------
 10                     0.0040680000000001s
 100                    0.011595s
 1000                   0.049718s
 10000                  0.457164s
 100000                 4s
 1000000                42s


            SELECT
------------------------------------------------
num of rows             time taken
------------------------------------------------
 1000000                <1s


            SELECT & DISPLAY
------------------------------------------------
num of rows             time taken
------------------------------------------------
  1000000               20s
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

________________________________________________
PHP5 with MongoDB 
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
            INSERT
------------------------------------------------
num of rows             time taken
------------------------------------------------
10                      0.065744s
100                     0.190966s
1000                    0.2163s
10000                   1s
100000                  8s
1000000                 78s


            FIND
------------------------------------------------
num of rows             time taken
------------------------------------------------
1000000                 <1s


            FIND & DISPLAY
------------------------------------------------
num of rows             time taken
------------------------------------------------
1000000                 7s


            UPDATE
------------------------------------------------
num of rows             time taken
------------------------------------------------
1000000                 9s

myisam non è innodb, anche quale versione mongodb e motore di archiviazione?

1
è importante specificare le versioni MySQL e MongoDB.
Miron,

1
Non usare MyISAM. Utilizzare inserti batch!
Rick James,

MySQL è più veloce di Mongodb nella query Inserisci ?! non sembra vero fino a quando mysql non dovrà preparare colonne e nuove relazioni. mysql select è più veloce di mongodb select, ma nella query di inserimento, mongo è più veloce
Exind

6

Ecco una piccola ricerca che ha esplorato RDBMS vs NoSQL usando MySQL vs Mongo, le conclusioni sono state in linea con la risposta di @Sean Reilly. In breve, il vantaggio deriva dal design, non da alcune differenze di velocità. Conclusione a pagina 35-36:

RDBMS vs NoSQL: confronto prestazioni e ridimensionamento

Il progetto ha testato, analizzato e confrontato le prestazioni e la scalabilità dei due tipi di database. Gli esperimenti effettuati includevano l'esecuzione di numeri e tipi diversi di query, alcune più complesse di altre, al fine di analizzare il ridimensionamento dei database con un carico maggiore. Il fattore più importante in questo caso è stato il tipo di query utilizzato in quanto MongoDB è in grado di gestire più rapidamente query più complesse a causa principalmente del suo schema più semplice a scapito della duplicazione dei dati, il che significa che un database NoSQL può contenere grandi quantità di duplicati dei dati. Sebbene sia possibile utilizzare uno schema migrato direttamente dall'RDBMS, ciò eliminerebbe il vantaggio della rappresentazione dei dati sottostanti di MongoDB dei documenti secondari che consentiva l'uso di meno query verso il database quando le tabelle venivano combinate.Nonostante il guadagno in termini di prestazioni che MongoDB ha ottenuto su MySQL in queste complesse query, quando il benchmark ha modellato la query MySQL in modo simile alla query complessa MongoDB utilizzando SELECT nidificati, MySQL ha funzionato meglio anche se a un numero più elevato di connessioni i due si sono comportati in modo simile. L'ultimo tipo di query confrontato, che era la query complessa contenente due JOIN, e una sottoquery hanno mostrato il vantaggio che MongoDB ha su MySQL grazie al suo uso di documenti secondari. Questo vantaggio deriva dal costo della duplicazione dei dati che provoca un aumento delle dimensioni del database. Se tali query sono tipiche in un'applicazione, è importante considerare i database NoSQL come alternative tenendo conto del costo di archiviazione e delle dimensioni della memoria risultanti dalle dimensioni del database più grandi.


-6

Su Single Server, MongoDb non sarebbe più veloce di mysql MyISAM sia in lettura che in scrittura, dato che le dimensioni di tabella / documento sono piccole da 1 GB a 20 GB.
MonoDB sarà più veloce su Parallel Reduce su cluster multi-nodo, dove Mysql NON può ridimensionare in orizzontale.


5
Potete fornire qualche prova o maggiori dettagli per sostenerlo?
Steve Westbrook

Non è possibile ridimensionare in orizzontale? Che dire di NDB? DRBD ha supportato MySQL?
Ernestas

Questo non è vero. MongoDB ha un limite di documenti 16MD. Mysql può avere molto di più se vuoi
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.