web-dev-qa-db-fra.com

MySQL vs MongoDB 1000 lectures

MongoDb me passionne et l’essaie récemment. J'avais une table appelée posts dans MySQL avec environ 20 millions d'enregistrements indexés uniquement sur un champ appelé "id".

Je voulais comparer la vitesse avec MongoDB et j'ai fait un test qui permettrait d’obtenir et d’imprimer 15 enregistrements de manière aléatoire à partir de nos énormes bases de données. J'ai couru la requête environ 1 000 fois pour mysql et MongoDB et je suis surpris que je ne remarque pas beaucoup de différence de vitesse. Peut-être que MongoDB est 1,1 fois plus rapide. C'est très décevant. Y a-t-il quelque chose que je fais mal? Je sais que mes tests ne sont pas parfaits, mais que MySQL est au même niveau que MongoDb en ce qui concerne la lecture de tâches intensives.


Remarque:

  • J'ai dual core + (2 threads) i7 cpu et 4 Go de RAM
  • J'ai 20 partitions sur MySQL sur 1 million d'enregistrements.

Exemple de code utilisé pour tester 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;
}

?>


Exemple de code pour tester 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;
}
?>
299
Imran Omar Bukhsh

MongoDB n'est pas magiquement plus rapide. Si vous stockez les mêmes données, organisées de la même manière et que vous y accédez exactement de la même manière, vous ne devriez vraiment pas vous attendre à ce que vos résultats soient extrêmement différents. Après tout, MySQL et MongoDB sont tous deux de la GPL. Si Mongo contenait du code IO magiquement meilleur, alors l'équipe de MySQL pourrait l'intégrer à sa base de code.

Les gens voient les performances de MongoDB dans le monde réel, en grande partie parce que MongoDB vous permet d’interroger d’une manière différente, plus sensible à votre charge de travail.

Par exemple, considérons une conception qui conserve de nombreuses informations sur une entité compliquée de manière normalisée. Cela pourrait facilement utiliser des dizaines de tables dans MySQL (ou n'importe quelle base de données relationnelle) pour stocker les données sous forme normale, avec de nombreux index nécessaires pour assurer l'intégrité relationnelle entre les tables.

Considérons maintenant la même conception avec un magasin de documents. Si toutes les tables liées sont subordonnées à la table principale (et le sont souvent), vous pourrez alors modéliser les données de manière à ce que l'entité entière soit stockée dans un seul document. Dans MongoDB, vous pouvez le stocker en tant que document unique, dans une seule collection. C'est là que MongoDB commence à permettre des performances supérieures.

Dans MongoDB, pour récupérer l'entité entière, vous devez effectuer:

  • Une recherche d'index sur la collection (en supposant que l'entité est extraite par id)
  • Récupérer le contenu d'une page de la base de données (le document json binaire actuel)

Donc, une recherche b-tree, et une page binaire lue. Log (n) + 1 E/S. Si les index peuvent résider entièrement en mémoire, 1 IO.

Dans MySQL avec 20 tables, vous devez effectuer:

  • Une recherche d'index sur la table racine (encore une fois, en supposant que l'entité est extraite par id)
  • Avec un index clusterisé, on peut supposer que les valeurs de la ligne racine sont dans l'index
  • 20 + plages de recherches (espérons sur un index) pour la valeur pk de l'entité
  • Ce ne sont probablement pas des index clusterisés, donc les mêmes 20+ recherches de données une fois que nous avons déterminé quelles sont les lignes enfants appropriées.

Donc, le total pour mysql, même en supposant que tous les index sont en mémoire (ce qui est plus difficile puisqu'il y en a 20 fois plus), est d'environ 20 recherches d'intervalles.

Ces recherches de plages sont probablement composées de IO aléatoires. Différentes tables résideront définitivement à des emplacements différents sur le disque. comment l’entité a été mise à jour, etc.).

Donc pour cet exemple, le décompte final est d'environ 20 fois plus IO avec MySQL par accès logique, par rapport à MongoDB.

Voilà comment MongoDB peut améliorer les performances dans certains cas d'utilisation.

607
Sean Reilly

Avez-vous des accès simultanés, c'est-à-dire des utilisateurs simultanés? Si vous exécutez simplement 1000 fois la requête, avec un seul thread, il n'y aura presque pas de différence. Trop facile pour ces moteurs :)

MAIS je vous suggère fortement de construire une session de test de charge réelle, ce qui signifie utiliser un injecteur tel que JMeter avec 10, 20 ou 50 utilisateurs AT THE MEME TEMPS pour que vous puissiez vraiment voir une différence (essayez de l'intégrer. code dans une page Web que JMeter pourrait interroger).

Je viens de le faire aujourd'hui sur un seul serveur (et une simple collection/table) et les résultats sont assez intéressants et surprenants (MongoDb était vraiment plus rapide en écriture et en lecture que le moteur MyISAM et le moteur InnoDb).

Cela devrait vraiment faire partie de votre test: accès simultané et moteur MySQL. Ensuite, la conception des données/schémas et les besoins des applications sont bien sûr énormes, au-delà des temps de réponse. Faites-moi savoir lorsque vous obtenez des résultats, j'ai également besoin d'informations à ce sujet!

54
theAndroid

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

10 rangées

mysql insert: 1702ms
mysql select: 11ms

mongo insert: 47ms
mongo select: 12ms

100 rangées

mysql insert: 8171ms
mysql select: 10ms

mongo insert: 167ms
mongo select: 60ms

1000 rangées

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

mongo insert: 1013ms
mongo select: 677ms

10.000 lignes

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

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

man , la réponse est que vous testez fondamentalement PHP et non une base de données.

ne vous embêtez pas en itérant les résultats, que ce soit en commentant l'impression ou non. il y a un morceau de temps.

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

tandis que l’autre partie dépense à dépouiller un tas de nombres de Rand.

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

    }
    return $numbers;
}

alors il y a une différence majeure b/w imploser et dans.

et enfin ce qui se passe ici. ressemble à créer une connexion à chaque fois, ainsi il teste le temps de connexion plus le temps de requête.

$m = new Mongo();

contre

$db = new AQLDatabase();

de sorte que votre 101% plus rapide pourrait s'avérer être 1000% plus rapide pour la requête sous-jacente dépourvue de jazz.

urghhh.

19
Gabe Rainbow

https://github.com/reoxey/benchmark

repère

comparaison de la vitesse de MySQL et MongoDB dans GOLANG 1.6 et PHP5

système utilisé pour le benchmark: GPU Dell i5 4ème génération 1.70Ghz * 4 RAM 4 Go GPU RAM 2 Go

Comparaison de la vitesse du SGBDR et de NoSQL pour INSERT, SELECT, UPDATE, DELETE et exécuter un nombre différent de lignes 10,100,1000,10000,100000,1000000

Le langage utilisé pour exécuter est: PHP5 et le langage le plus rapide de 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
16
Reoxey

Voici n peu de recherche qui a exploré SGBDR vs NoSQL en utilisant MySQL vs Mongo, les conclusions étaient cohérentes avec la réponse de @Sean Reilly. En bref, l'avantage réside dans la conception, et non dans une différence de vitesse brute. Conclusion aux pages 35-36:

SGBDR vs NoSQL: Comparaison des performances et de la mise à l'échelle

Le projet a testé, analysé et comparé les performances et l'évolutivité des deux types de bases de données. Les expériences effectuées incluaient différents nombres et types de requêtes, certaines plus complexes que d'autres, afin d'analyser la manière dont les bases de données évoluaient avec une charge accrue. Dans ce cas, le facteur le plus important était le type de requête utilisé, car MongoDB pouvait traiter des requêtes plus complexes plus rapidement, principalement en raison de son schéma plus simple, au lieu de la duplication de données, ce qui signifie qu'une base de données NoSQL peut contenir de grandes quantités de doublons. Bien qu’un schéma directement migré du SGBDR puisse être utilisé, cela éliminerait l’avantage de la représentation sous-jacente des données par MongoDB, qui permettait d’utiliser moins de requêtes vers la base de données lors de la combinaison des tables. Malgré le gain de performances que MongoDB avait sur MySQL dans ces requêtes complexes, lorsque le test a modélisé la requête MySQL de la même manière que la requête complexe MongoDB en utilisant des commandes SELECT imbriquées, MySQL s'est mieux comporté Le dernier type de requête comparé, qui était la requête complexe contenant deux JOINS et une sous-requête, montrait l'avantage que MongoDB avait par rapport à MySQL. en raison de son utilisation de sous-documents. Cet avantage a un coût de duplication des données qui entraîne une augmentation de la taille de la base de données. Si de telles requêtes sont typiques dans une application, il est important de considérer les bases de données NoSQL comme des alternatives, tout en tenant compte du coût en stockage et en taille de la mémoire résultant de la taille plus grande de la base de données.

4
Jason Hitchings