it-swarm.com.de

MySQL vs MongoDB 1000 liest

Ich war sehr aufgeregt über MongoDb und habe es in letzter Zeit getestet. Ich hatte eine Tabelle namens posts in MySQL mit ungefähr 20 Millionen Datensätzen, die nur in einem Feld namens 'id' indiziert waren.

Ich wollte die Geschwindigkeit mit MongoDB vergleichen und führte einen Test durch, bei dem 15 Datensätze zufällig aus unseren riesigen Datenbanken abgerufen und gedruckt wurden. Ich habe die Abfrage für MySQL und MongoDB jeweils ungefähr 1.000 Mal ausgeführt und bin überrascht, dass ich keinen großen Geschwindigkeitsunterschied bemerke. Vielleicht ist MongoDB 1.1 mal schneller. Das ist sehr enttäuschend. Gibt es etwas, was ich falsch mache? Ich weiß, dass meine Tests nicht perfekt sind, aber MySQL ist mit MongoDb auf Augenhöhe, wenn es um das Lesen intensiver Aufgaben geht.


Hinweis:

  • Ich habe Dual Core + (2 Threads) i7 CPU und 4 GB RAM
  • Ich habe 20 Partitionen auf MySQL mit jeweils 1 Million Datensätzen

Beispielcode zum Testen von 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;
}

?>


Beispielcode zum Testen von 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

MongoDB ist nicht magisch schneller. Wenn Sie dieselben Daten speichern, im Wesentlichen auf dieselbe Weise organisieren und auf dieselbe Weise darauf zugreifen, sollten Sie wirklich nicht erwarten, dass Ihre Ergebnisse stark voneinander abweichen. Schließlich sind MySQL und MongoDB beide GPL. Wenn Mongo also einen magisch besseren IO Code enthält, könnte das MySQL-Team ihn einfach in seine Codebasis integrieren.

Menschen sehen die Leistung von MongoDB in der Praxis hauptsächlich deshalb, weil Sie mit MongoDB auf eine andere Art und Weise abfragen können, die für Ihre Arbeitslast sinnvoller ist.

Stellen Sie sich zum Beispiel ein Design vor, das viele Informationen über eine komplizierte Entität auf normalisierte Weise beibehält. Dies könnte leicht Dutzende von Tabellen in MySQL (oder einer relationalen Datenbank) verwenden, um die Daten in normaler Form zu speichern, wobei viele Indizes erforderlich sind, um die relationale Integrität zwischen Tabellen sicherzustellen.

Betrachten Sie nun dasselbe Design mit einem Dokumentenspeicher. Wenn alle diese verknüpften Tabellen der Haupttabelle untergeordnet sind (und dies häufig der Fall ist), können Sie die Daten möglicherweise so modellieren, dass die gesamte Entität in einem einzigen Dokument gespeichert wird. In MongoDB können Sie dieses Dokument als einzelnes Dokument in einer einzelnen Sammlung speichern. Hier setzt MongoDB an und ermöglicht eine überlegene Leistung.

In MongoDB müssen Sie Folgendes ausführen, um die gesamte Entität abzurufen:

  • Eine Indexsuche in der Auflistung (vorausgesetzt, die Entität wird von id abgerufen)
  • Abrufen des Inhalts einer Datenbankseite (des eigentlichen binären JSON-Dokuments)

Also ein B-Tree-Lookup und eine Binärseite lesen. Log (n) + 1 IOs. Wenn sich die Indizes vollständig im Arbeitsspeicher befinden können, ist 1 E/A.

In MySQL mit 20 Tabellen müssen Sie Folgendes ausführen:

  • Eine Indexsuche in der Stammtabelle (wiederum unter der Annahme, dass die Entität von id abgerufen wird)
  • Bei einem Clustered-Index können wir davon ausgehen, dass sich die Werte für die Stammzeile im Index befinden
  • Über 20 Range Lookups (hoffentlich in einem Index) für den pk-Wert der Entität
  • Da es sich wahrscheinlich nicht um Clustered-Indizes handelt, werden die gleichen mehr als 20 Datensuchen ausgeführt, sobald die entsprechenden untergeordneten Zeilen ermittelt wurden.

Die Summe für mysql, selbst wenn alle Indizes im Speicher sind (was schwieriger ist, da es 20-mal mehr davon gibt), beträgt ungefähr 20 Bereichssuchvorgänge.

Diese Bereichssuchen bestehen wahrscheinlich aus zufälligen IO - verschiedene Tabellen befinden sich definitiv an verschiedenen Stellen auf dem Datenträger, und es ist möglich, dass verschiedene Zeilen im gleichen Bereich in derselben Tabelle für eine Entität möglicherweise nicht zusammenhängend sind (abhängig davon) wie das Unternehmen aktualisiert wurde, usw.).

In diesem Beispiel ist die endgültige Anzahl also ungefähr 20 Mal more IO mit MySQL pro logischem Zugriff im Vergleich zu MongoDB.

Auf diese Weise kann MongoDB die Leistung steigern in einigen Anwendungsfällen.

607
Sean Reilly

Haben Sie Parallelität, d. H. Gleichzeitige Benutzer? Wenn Sie die Abfrage gerade 1000-mal mit nur einem Thread ausführen, gibt es fast keinen Unterschied. Zu einfach für diese Motoren :)

ABER ich empfehle dringend, dass Sie eine echte Belastungstestsitzung aufbauen, was bedeutet, dass Sie einen Injektor wie JMeter mit 10, 20 oder 50 Benutzern AT GLEICHZEITIG verwenden, damit Sie wirklich einen Unterschied feststellen können (versuchen Sie, diesen einzubetten) Code innerhalb einer Webseite, den JMeter abfragen könnte).

Ich habe es heute auf einem einzelnen Server (und einer einfachen Sammlung/Tabelle) gemacht und die Ergebnisse sind sehr interessant und überraschend (MongoDb war beim Schreiben und Lesen im Vergleich zur MyISAM-Engine und der InnoDb-Engine wirklich schneller).

Dies sollte wirklich Teil Ihres Tests sein: Parallelität und MySQL-Engine. Dann sind die Anforderungen an Daten-/Schemadesign und -anwendung natürlich über die Antwortzeiten hinaus sehr hoch. Lassen Sie mich wissen, wenn Sie Ergebnisse erhalten, ich bin auch auf Eingaben dazu angewiesen!

54
theAndroid

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

10 Reihen

mysql insert: 1702ms
mysql select: 11ms

mongo insert: 47ms
mongo select: 12ms

100 Zeilen

mysql insert: 8171ms
mysql select: 10ms

mongo insert: 167ms
mongo select: 60ms

1000 Zeilen

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

mongo insert: 1013ms
mongo select: 677ms

10.000 Zeilen

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

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

mann, die Antwort ist, dass Sie im Grunde genommen PHP und keine Datenbank testen.

machen Sie sich nicht die Mühe, die Ergebnisse zu iterieren, egal ob Sie den Ausdruck auskommentieren oder nicht. Es gibt ein bisschen Zeit.

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

während der andere Teil eine Menge Rand-Zahlen einsammelt.

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

    }
    return $numbers;
}

dann gibt es einen großen Unterschied zwischen s/w implodieren und in.

und endlich was hier los ist. Es sieht so aus, als würde jedes Mal eine Verbindung hergestellt, daher wird die Verbindungszeit plus die Abfragezeit getestet.

$m = new Mongo();

vs

$db = new AQLDatabase();

ihre 101% -ige Geschwindigkeit könnte sich für die zugrunde liegende Abfrage des Jazz als 1000% -ige Geschwindigkeit herausstellen.

urghhh.

19
Gabe Rainbow

https://github.com/reoxey/benchmark

Benchmark

geschwindigkeitsvergleich von MySQL & MongoDB in GOLANG1.6 & PHP5

system für Benchmark verwendet: Dell CPU i5 4. Generation 1,70 GHz * 4 RAM 4 GB GPU RAM 2 GB

Geschwindigkeitsvergleich von RDBMS mit NoSQL für INSERT, SELECT, UPDATE, DELETE, wobei eine unterschiedliche Anzahl von Zeilen 10,100,1000,10000,100000,1000000 ausgeführt wird

Die zur Ausführung verwendete Sprache ist: PHP5 & Google schnellste Sprache 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

Hier ist eine kleine Recherche , die RDBMS vs NoSQL mit MySQL vs Mongo untersuchte. Die Schlussfolgerungen stimmten mit der Antwort von @Sean Reilly überein. Kurz gesagt, der Vorteil liegt im Design und nicht in einem groben Geschwindigkeitsunterschied. Fazit auf Seite 35-36:

RDBMS vs NoSQL: Leistungs- und Skalierungsvergleich

Das Projekt testete, analysierte und verglich die Leistung und Skalierbarkeit der beiden Datenbanktypen. Die durchgeführten Experimente umfassten das Ausführen unterschiedlicher Anzahlen und Arten von Abfragen, von denen einige komplexer als andere sind, um zu analysieren, wie die Datenbanken mit zunehmender Auslastung skaliert wurden. Der wichtigste Faktor in diesem Fall war der Abfragetyp, der verwendet wurde, da MongoDB komplexere Abfragen schneller verarbeiten konnte, hauptsächlich aufgrund seines einfacheren Schemas bei der Aufopferung von Datenduplikaten, was bedeutet, dass eine NoSQL-Datenbank große Mengen von Datenduplikaten enthalten kann. Obwohl ein direkt aus dem RDBMS migriertes Schema verwendet werden könnte, würde dies den Vorteil der zugrunde liegenden Datendarstellung von Filialdokumenten in MongoDB beseitigen, der die Verwendung von weniger Abfragen in Bezug auf die Datenbank beim Kombinieren von Tabellen ermöglichte. Trotz des Leistungsgewinns, den MongoDB bei diesen komplexen Abfragen gegenüber MySQL hatte, schnitt die Modellierung der MySQL-Abfrage durch den Benchmark ähnlich wie bei der komplexen Abfrage von MongoDB mit verschachtelten SELECTs von MySQL am besten ab Bei einer höheren Anzahl von Verbindungen verhielten sich die beiden ähnlich. Die letzte Art von Benchmark-Abfrage, bei der es sich um die komplexe Abfrage mit zwei JOINS und einer Unterabfrage handelte, zeigte den Vorteil von MongoDB gegenüber MySQL aufgrund seiner Verwendung von Filialdokumenten. Dieser Vorteil geht zu Lasten der Datenvervielfältigung, die zu einer Vergrößerung der Datenbank führt. Wenn solche Abfragen in einer Anwendung typisch sind, ist es wichtig, NoSQL-Datenbanken als Alternative zu betrachten und dabei die Kosten für Speicher und Speichergröße zu berücksichtigen, die sich aus der größeren Datenbankgröße ergeben.

4
Jason Hitchings