379 Stimmen

MySQL vs. MongoDB 1000 Lesungen

Ich war sehr begeistert von MongoDb und habe es in letzter Zeit getestet. Ich hatte eine Tabelle namens posts in MySQL mit etwa 20 Millionen Datensätzen, die nur auf einem Feld namens "id" indiziert waren.

Ich wollte die Geschwindigkeit mit MongoDB vergleichen und habe einen Test durchgeführt, bei dem 15 Datensätze zufällig aus unseren riesigen Datenbanken abgerufen und gedruckt wurden. Ich habe die Abfrage jeweils etwa 1.000 Mal für mysql und MongoDB ausgeführt und bin überrascht, dass ich keinen großen Geschwindigkeitsunterschied feststellen konnte. Vielleicht ist MongoDB 1,1 Mal schneller. Das ist sehr enttäuschend. Mache ich etwas falsch? Ich weiß, dass meine Tests nicht perfekt sind, aber ist MySQL mit MongoDb gleichauf, wenn es um leseintensive Aufgaben geht?

Anmerkung:

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

Beispielcode für das 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;
}
?>

737voto

Sean Reilly Punkte 20866

MongoDB ist nicht auf magische Weise schneller. Wenn Sie dieselben Daten speichern, sie im Grunde genommen auf dieselbe Weise organisieren und auf sie auf genau dieselbe Weise zugreifen, sollten Sie nicht erwarten, dass sich Ihre Ergebnisse grundlegend unterscheiden. Schließlich stehen sowohl MySQL als auch MongoDB unter der GPL. Wenn also Mongo einen magisch verbesserten IO-Code enthielte, könnte das MySQL-Team diesen einfach in seine Codebasis einbauen.

Die Leute sehen die Leistung von MongoDB in der realen Welt vor allem deshalb, weil MongoDB es Ihnen ermöglicht, Abfragen auf eine andere Art und Weise durchzuführen, die für Ihre Arbeitslast sinnvoller ist.

Nehmen wir zum Beispiel einen Entwurf, der viele Informationen über eine komplizierte Entität in normalisierter Form aufbewahrt. Dazu könnten leicht Dutzende von Tabellen in MySQL (oder einer anderen relationalen Datenbank) verwendet werden, um die Daten in normaler Form zu speichern, wobei viele Indizes erforderlich wären, um die relationale Integrität zwischen den Tabellen zu gewährleisten.

Betrachten Sie nun das gleiche Design mit einer Dokumentenablage. Wenn alle zugehörigen Tabellen der Haupttabelle untergeordnet sind (und das sind sie oft), können Sie die Daten so modellieren, dass die gesamte Entität in einem einzigen Dokument gespeichert wird. In MongoDB können Sie dies als ein einziges Dokument in einer einzigen Sammlung speichern. An dieser Stelle beginnt MongoDB, eine überlegene Leistung zu ermöglichen.

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

  • Eine Indexabfrage in der Sammlung (unter der Annahme, dass die Entität nach der ID abgerufen wird)
  • Abrufen des Inhalts einer Datenbankseite (das eigentliche binäre json-Dokument)

Also ein B-Tree-Lookup und ein binäres Seitenlesen. Log(n) + 1 IOs. Wenn sich die Indizes vollständig im Speicher befinden können, dann 1 IO.

In MySQL mit 20 Tabellen müssen Sie diese Aufgabe erfüllen:

  • Eine Indexabfrage in der Root-Tabelle (wiederum unter der Annahme, dass die Entität nach der ID abgerufen wird)
  • Bei einem geclusterten Index können wir davon ausgehen, dass die Werte für die Root-Zeile im Index stehen
  • 20+ Bereichsabfragen (hoffentlich über einen Index) für den pk-Wert der Entität
  • Wahrscheinlich handelt es sich nicht um geclusterte Indizes, so dass die gleichen 20+ Datenabfragen erfolgen, sobald wir herausgefunden haben, was die entsprechenden untergeordneten Zeilen sind.

Also die insgesamt für mysql, auch unter der Annahme, dass alle Indizes im Speicher sind (was schwieriger ist, da es 20 mal mehr von ihnen) ist etwa 20 Bereich Lookups.

Diese Bereichsabfragen bestehen wahrscheinlich aus zufälligem IO - verschiedene Tabellen befinden sich definitiv an verschiedenen Stellen auf der Festplatte, und es ist möglich, dass verschiedene Zeilen im selben Bereich in derselben Tabelle für eine Entität nicht zusammenhängend sind (je nachdem, wie die Entität aktualisiert wurde usw.).

Für dieses Beispiel ergibt sich also eine Gesamtsumme von etwa 20 Mal mehr IO mit MySQL pro logischem Zugriff, verglichen mit MongoDB.

So kann MongoDB die Leistung steigern in einigen Anwendungsfällen .

67voto

theAndroid Punkte 794

Haben Sie Gleichzeitigkeit, d.h. gleichzeitige Benutzer? Wenn Sie die Abfrage 1000-mal direkt mit nur einem Thread ausführen, wird es kaum einen Unterschied geben. Zu einfach für diese Motoren :)

ABER ich schlage dringend vor, dass Sie einen echten Lasttest durchführen, d. h. einen Injektor wie JMeter mit 10, 20 oder 50 Benutzern zur gleichen Zeit verwenden, damit Sie wirklich einen Unterschied sehen können (versuchen Sie, diesen Code in eine Webseite einzubetten, die JMeter abfragen könnte).

Ich habe es gerade heute auf einem einzelnen Server (und einer einfachen Sammlung/Tabelle) ausprobiert und die Ergebnisse sind recht interessant und überraschend (MongoDb war beim Schreiben und Lesen wirklich schneller als die MyISAM- und InnoDb-Engine).

Dies sollte wirklich Teil Ihres Tests sein: Gleichzeitigkeit und MySQL-Engine. Dann sind Daten-/Schemadesign und Anwendungsbedürfnisse natürlich große Anforderungen, die über die Antwortzeiten hinausgehen. Lassen Sie mich wissen, wenn Sie Ergebnisse erhalten, ich brauche auch Input zu diesem Thema!

36voto

user2081518 Punkte 696

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)

25voto

Gabe Rainbow Punkte 3510

Mann,,, die Antwort ist, dass Sie im Grunde PHP und nicht eine Datenbank testen.

Machen Sie sich nicht die Mühe, die Ergebnisse zu iterieren, unabhängig davon, ob Sie den Ausdruck auskommentieren oder nicht. es ist eine Menge Zeit.

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

während der andere Teil damit verbracht wird, einen Haufen von Randnummern aufzuschwatzen.

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 implodieren und in.

und schließlich, was hier vor sich geht. sieht aus wie eine Verbindung jedes Mal zu erstellen, so seine Prüfung der Verbindungszeit plus die Abfragezeit.

$m = new Mongo();

gegen

$db = new AQLDatabase();

so dass Ihre 101% schneller könnte sich als 1000% schneller für die zugrunde liegende Abfrage stripped of jazz sein.

urghhh.

25voto

reoxey Punkte 684

https://github.com/reoxey/benchmark

Benchmark

Geschwindigkeitsvergleich von MySQL & MongoDB in GOLANG1.6 & PHP5

System für den Benchmark verwendet: DELL cpu i5 4th gen 1.70Ghz * 4 ram 4GB GPU ram 2GB

Geschwindigkeitsvergleich zwischen RDBMS und NoSQL für INSERT, SELECT, UPDATE, DELETE bei der Ausführung verschiedener Anzahl von Zeilen 10, 100, 1000, 10000, 100000, 1000000

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X