MySQL ve MongoDB 1000 okumaları


320

MongoDb hakkında çok heyecanlandım ve son zamanlarda test ediyorum. MySQL'de mesajlar olarak adlandırılan bir tablo vardı ve yaklaşık 20 milyon kayıt sadece 'id' adı verilen bir alanda indekslendi.

Hızı MongoDB ile karşılaştırmak istedim ve devasa veritabanlarımızdan rasgele 15 kayıt alıp yazdıracağım bir test yaptım. Sorguyu mysql ve MongoDB için yaklaşık 1.000 kez çalıştırdım ve hızda çok fazla fark görmediğime şaşırdım. Belki MongoDB 1.1 kat daha hızlıdır. Bu çok hayal kırıklığı yaratıyor. Yanlış yaptığım bir şey var mı? Testlerimin mükemmel olmadığını biliyorum ama yoğun işleri okumak söz konusu olduğunda MongoDb ile eşit MySQL.


Not:

  • Çift çekirdekli + (2 iş parçacığı) i7 cpu ve 4GB ram var
  • MySQL'de her biri 1 milyon kayıttan 20 bölüm var

MongoDB Testinde Kullanılan Örnek Kod

<?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;
}

?>


MySQL Testi için Örnek Kod

<?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
Gerçek zamanlar nelerdir?
Abe Petrillo

30
Ben bir DBA değilim bu yüzden bu bir cevap değil bir yorum, ancak hız MySQL ve MongoDB arasında seçim ana dikkate olmamalıdır. Şema veya şema (yani veri şemanızın ne sıklıkta değişmesi gerekir) ve boyutlandırma (örneğin, tipik bir okumanın yalnızca bir sunucudan veri gerektirmesi için verilerinizi parçalamak ne kadar kolaydır) gibi bir seçim için daha önemlidir bunun gibi.
rossdavidh

17
Okumada nasıl daha hızlı olabilir? Mekanik bir cihazdan okur. MySQL ile aynı. Cihazın hızına bağlıdır, donanımın sınırlarını aşmak için kod aracılığıyla garip bir sihir kullanamazsınız.
NB

7
Bu soru bana şunu hatırlatıyor: mongodb-is-web-scale.com
oligofren

13
İnsanlar bir ya da başka biriyle birlikte gideceklerini düşünüyorlar. Mutfağınızda hem mikrodalgaya hem de fırına ihtiyacınız olacak. Sadece birini ya da diğerini kullanacağımı söyleyemezsin. Her iki sistem için kullanım durumları farklıdır. Uygulamanızın bir kısmı için ACID'ye ihtiyacınız varsa, tutarlılık ve kısıtlamalarla ilgilenmiyorsanız RDBMS'yi kullanın ve varlıklarınız hepsi bir arada (koleksiyonlar) olarak saklanabilir, sonra MongoDB'yi kullanın. Bir hibrit sistem kullanacaksınız, kilit nokta nerede depolanacağına karar vermektir.
Teoman shipahi

Yanıtlar:


646

MongoDB sihirli bir şekilde daha hızlı değildir. Aynı verileri temelde aynı şekilde düzenler ve tam olarak aynı şekilde erişirseniz, sonuçlarınızın çılgınca farklı olmasını beklememelisiniz. Sonuçta, MySQL ve MongoDB'nin her ikisi de GPL'dir, bu nedenle Mongo'nun sihirli olarak daha iyi bir IO kodu varsa, MySQL ekibi onu kod tabanlarına dahil edebilir.

İnsanlar gerçek dünya MongoDB performansını büyük ölçüde görüyor çünkü MongoDB, iş yükünüze daha duyarlı farklı bir şekilde sorgulamanıza izin veriyor.

Örneğin, karmaşık bir varlık hakkında normalleştirilmiş bir şekilde birçok bilgiye devam eden bir tasarım düşünün. Bu, verileri normal formda saklamak için MySQL'deki (veya herhangi bir ilişkisel db) düzinelerce tabloyu kolayca kullanabilir ve tablolar arasındaki ilişkisel bütünlüğü sağlamak için birçok dizin gerekir.

Şimdi aynı tasarımı bir belge deposuyla düşünün. İlgili tüm tablolar ana tabloya bağlıysa (ve genellikle öyleyse), verileri tüm varlığın tek bir belgede saklanacağı şekilde modelleyebilirsiniz. MongoDB'de bunu tek bir koleksiyonda tek bir belge olarak saklayabilirsiniz. Burası MongoDB'nin üstün performans sağlamaya başladığı yerdir.

MongoDB'de tüm varlığı almak için şunları yapmanız gerekir:

  • Koleksiyonda bir dizin araması (varlığın kimliğe getirildiği varsayılarak)
  • Bir veritabanı sayfasının içeriğini (gerçek ikili json belgesi) alın

Böylece bir b-ağacı araması ve bir ikili sayfa okunur. Log (n) + 1 ES. Dizinler tamamen bellekte bulunabilirse, 1 IO.

20 tablolu MySQL'de şunları yapmanız gerekir:

  • Kök tabloda bir dizin araması (yine, varlığın id tarafından getirildiği varsayılarak)
  • Kümelenmiş bir dizinle, kök satır değerlerinin dizinde olduğunu varsayabiliriz
  • Varlığın pk değeri için 20'den fazla aralık araması (umarım bir dizinde)
  • Bunlar muhtemelen kümelenmiş dizinler değildir, bu nedenle uygun alt satırların ne olduğunu anladığımızda aynı 20'den fazla veri arar.

Yani, mysql için toplam, hatta tüm dizinlerin bellekte olduğunu varsayarsak (20 kat daha fazla olduğu için daha zordur) yaklaşık 20 menzil aramasıdır.

Bu aralık aramaları muhtemelen rastgele IO'dan oluşur - farklı tablolar kesinlikle diskteki farklı noktalarda bulunur ve bir varlık için aynı tabloda aynı aralıktaki farklı satırların bitişik olmayabilir (varlığın nasıl olduğuna bağlı olarak) güncellendi, vb.).

Bu örnek için, son hesap, mantıksal erişim başına MySQL ile MongoDB'ye göre yaklaşık 20 kat daha fazla IO'dur.

MongoDB, bazı kullanım durumlarında performansı bu şekilde artırabilir .


43
mysql'e bir ana tablo koyarsak ne olur?
ariso

99
@ariso: Bu, denormalizasyon yoluyla optimizasyon. Performans artışı sağlayabilir. Ancak, bunu yaparsanız, temiz tasarımınızı ve ilişkisel bir veritabanının tüm gücünü (özelliklerin çoğundan bahsetmemek) atarsınız. Ve sadece sütun sınırına ulaşana kadar gerçekten işe yarıyor.
Sean Reilly

7
@SeanReilly Varlıklarla ilgili örnek (nesnelerle düzenlenmelidir, varlık odaklı programlama yoktur :)) geçersiz. Ariso'nun dediği gibi, bir nesneyi serileştirebilir ve db'de saklayabilir ve gerektiğinde serileştirebilirsiniz (herhangi bir serileştirme). Kalıcı nesnelerin gerçek gücü, documnet db sistemlerinde değil, oodbms'de tutulur. Ancak, her birinin kendi amacı ve güçlü yönleri olduğunu kabul ediyorum (ancak örneğiniz bu konunun vizyonunu ve alaka düzeyini daha fazla gizliyor).
Geo

9
20 birleşimler, söyleyebilirim, büyük olasılıkla bu olabilecek en iyi veritabanı şemasında en iyi sorgu değil.
Audrius Meskauskas

8
@SeanReilly Örneğinizi çok yararlı buldum. Nesneleri tablolara otomatik olarak serileştiren ve serileştiren ve mongodb'un yaptığı gibi davranan MySQL için özel bir arayüz oluşturabilirsiniz. Ama o zaman neden sadece bu şekilde kullanılmak üzere özel olarak tasarlanmış bir şey kullanmıyorsunuz? Ayrıca "varlık" kullanımınız da anlamlıdır. Buradaki nokta, verileri bir tablodaki alanlar yerine belgeler olarak düzenlediğinizdir. Belgenin OO dilinde oluşturulmuş bir nesne olup olmadığı örnekle alakasızdır.
BHS

57

Eşzamanlılığınız, yani eşzamanlı kullanıcılarınız var mı? Sorgunun 1000 katını düz bir şekilde çalıştırırsanız, tek bir iş parçacığı ile neredeyse hiçbir fark olmaz. Bu motorlar için çok kolay :)

AMA gerçek bir yük testi oturumu oluşturmanızı şiddetle tavsiye ederim, bu da gerçekten bir fark görebilmeniz için 10, 20 veya 50 kullanıcılı JMeter gibi bir enjektör kullanılması anlamına gelir (bu kodu bir web sayfasına yerleştirmeye çalışın JMeter sorgulayabilir).

Bugün tek bir sunucuda (ve basit bir koleksiyon / tablo) yaptım ve sonuçlar oldukça ilginç ve şaşırtıcı (MongoDb, MyISAM motoru ve InnoDb motoruna kıyasla yazma ve okumalarda gerçekten daha hızlıydı).

Bu gerçekten testinizin bir parçası olmalıdır: eşzamanlılık ve MySQL motoru. Daha sonra, veri / şema tasarımı ve uygulama ihtiyaçları elbette yanıt sürelerinin ötesinde büyük gereksinimlerdir. Sonuç aldığınızda bana bildirin, bununla ilgili girdilere de ihtiyacım var!


42
Sonuçları paylaşabilir misiniz?
Imran Omar Bukhsh

1
Ya, bunun sonuçları çok yardımcı olacak
Vasil Popov

3
Şüphesiz bu sadece ölçeklendirirdi ... eğer bu konunun geri kalanında söyledikleri gibi Elmalar için Elma ise. Eğer avg üzerinde x yaparsa, şimdi birden fazla kaynaktan simüle ederseniz, lütfen mongo'nun neden daha hızlı olacağını açıklayın. yani sadece anlaşma uğruna mysql tek bir istek için avg daha hızlı olduğunu söyleyelim ... mongo neden birden çok için daha hızlı olur? Bunu çok bilimsel bulmuyorum. Testin geçerli olduğunu söylüyorum .. ama konunun geri kalanı gibi Elma ile Elma karşılaştırırsanız farkın ne kadar büyük olacağından emin değilim.
Seabizkit

35

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

10 sıra

mysql insert: 1702ms
mysql select: 11ms

mongo insert: 47ms
mongo select: 12ms

100 sıra

mysql insert: 8171ms
mysql select: 10ms

mongo insert: 167ms
mongo select: 60ms

1000 sıra

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

mongo insert: 1013ms
mongo select: 677ms

10.000 satır

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

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

91
10.000 satır eklemek için 15 dakika? Bu çok anemik bir MySQL veritabanı. Deneyimlerime göre, böyle bir işlem 1 saniyeye yaklaşırsa, telefonum şikayetlerle yanar. :)
Mordechai

1
Xtreme Biker bağlantıya bir göz atın. Testi diğer ayarlarla başkalarından yayınladım.
user2081518

14
Birkaç nokta: 1) MySQL'in uygun şekilde optimize edilmesi ve yapılandırılması gerekir, büyük miktarda veri eklemek için birçok farklı yol vardır ve düzgün bir şekilde yapılması 15 dakikanın% 0.1'ini alabilir, örneğin bu sayfaya bakın . 2) MongoDB verileri diske hemen yazmaz, bu yüzden daha hızlı "görünür", ancak bilgisayarınız çökerse veriler kaybolur. 3)
MySQL'de

81
10.000 satır için 15dk? Her satırı mı yazdınız? =))))
Iurie Manea

7

20

man ,,, cevap temelde bir veritabanı değil, PHP test olmasıdır.

Baskıyı yorumlayıp yapmadığınızı, sonuçları yinelemekten rahatsız etmeyin. bir yığın zaman var.

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

diğer yığın bir sürü rand sayılarını emmek harcamak iken.

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

    }
    return $numbers;
}

sonra s / b emplode ve in arasında büyük bir fark vardır.

ve son olarak burada neler oluyor. her seferinde bir bağlantı oluşturmak gibi görünüyor, bu yüzden bağlantı süresini artı sorgu süresini test ediyor.

$m = new Mongo();

vs

$db = new AQLDatabase();

böylece% 101 daha hızlı olan cazın altında yatan sorgu için% 1000 daha hızlı olabilir.

urghhh.


4
doğal olarak, kodlama uygulaması her durumda büyük bir fark yaratabilir, ancak bu herhangi bir dil, API veya uzantıya özgü değildir. zamanlayıcıyı başlatmadan önce rasgele sayılar üretmek bir fark yaratacaktır, ancak süreç içindeki zamanın çoğunluğu veritabanı işlemlerinden şüphesizdir. rastgele sayı üretimi önemsiz, SQL ve NoSQL veritabanları değildir.
JSON

1
Rand numarasını seçmeyin. Her seferinde oluşturma bağlantısını açıkça kaçırdınız. tüm sorunlar, amaçlanandan başka bir şeyi test etmeye katkıda bulunur.
Gabe Rainbow

2
Hayır, kaçırmadım. MySQL, mysqli_close () çağrılmadığı sürece komut dosyası bitene kadar bağlantıyı kapatmaz. Aksi takdirde, mysqli_connect () öğesine yapılan yinelenen çağrılar, yeni bir bağlantı yordamına başvurmak yerine yalnızca varolan mysql kaynağını geçerli kaynak tablosundan alır. AQLDatabase nesnesinin tam olarak ne olduğundan emin değilim, ancak mysql lib'i kullanıyorsa (ki muhtemelen) aynı davranışa sahip olacaktır. MongoDB uzantısı bağlantı havuzu kullanır, bu nedenle aynı temel şey bir kodda bir mongodb 'bağlantısı' oluştururken oluşur.
JSON

Karşılaştırmasının farklı şekilde yapılabileceğini kabul ediyorum, ancak gördüğüm diğer MySQL vs Mongo tezgahlarıyla aynı temel sonuçları yansıtıyor. Mongo takarken genellikle daha hızlıdır (daha basit uçlar için çok daha hızlı) ve MySQL seçerken daha hızlıdır.
JSON

Kuşkusuz, çok huysuzdum; "gerçekten" html string concat beni gerçekten 'teşvik' oldu. testlerde güzel baskıya ihtiyacınız yok. yineleme bile bir veritabanı testi değil, bir php testi gibi görünüyor. genel olarak, AQLDatabase 'muhtemelen / belki' anı ... daha fazla içerik daha fazla bilinmeyen anlamına gelir.
Gabe Rainbow

17

https://github.com/reoxey/benchmark

kıyaslama

GOLANG1.6 ve PHP5'te MySQL ve MongoDB'nin hızlı karşılaştırması

kıyaslama için kullanılan sistem: DELL cpu i5 4. nesil 1.70Ghz * 4 ram 4GB GPU ram 2GB

RDBMS vs NoSQL için INSERT, SELECT, UPDATE, DELETE için farklı satırların 10,100,1000,10000,100000,1000000 hız karşılaştırması

Yürütmek için kullanılan dil: PHP5 ve Google'ın en hızlı dili 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 innodb değil, aynı zamanda hangi mongodb sürümü ve depolama motoru?

1
MySQL ve MongoDB sürümlerini belirtmek önemlidir.
Miron

1
MyISAM kullanmayın. Toplu kesici uçlar kullanın!
Rick James

Ekle sorgusunda MySQL Mongodb daha hızlı ?! mysql sütunları ve yeniden ilişkileri hazırlamak gerekene kadar doğru gibi görünmüyor. mysql select mongodb select daha hızlı, ancak insert sorgusunda, mongo daha hızlı
Exind

6

İşte MySQL vs Mongo kullanarak RDBMS vs NoSQL inceleyen küçük bir araştırma , sonuçlar @Sean Reilly yanıt ile inline edildi. Kısacası, fayda ham hız farkından değil tasarımdan gelir. 35-36. Sayfadaki sonuç:

RDBMS ve NoSQL: Performans ve Ölçekleme Karşılaştırması

Proje, iki veritabanı türünün performansını ve ölçeklenebilirliğini test etti, analiz etti ve karşılaştırdı. Yapılan deneyler, veritabanlarının artan yükle nasıl ölçeklendiğini analiz etmek için, bazıları diğerlerinden daha karmaşık olan farklı sayı ve türde sorguların çalıştırılmasını içermiştir. Bu durumda en önemli faktör, MongoDB olarak kullanılan sorgu türünün, esas olarak veri çoğaltmanın fedakarlığındaki daha basit şeması nedeniyle daha karmaşık sorguları daha hızlı işleyebilmesiydi; RDBMS'den doğrudan taşınan bir şema kullanılabilmesine rağmen, bu, MongoDB'nin tablolar birleştirilirken veritabanına daha az sorgu kullanılmasına izin veren alt belgelerin temeldeki veri sunumunun avantajını ortadan kaldıracaktır.MongoDB'nin bu karmaşık sorgularda MySQL üzerinde sahip olduğu performans kazanımına rağmen, karşılaştırma ölçütü MySQL sorgusunu MongoDB karmaşık sorgusuna benzer şekilde modellediğinde, iç içe SELECT'ler kullanarak MySQL en iyi performansı sergiledi, ancak daha fazla sayıda bağlantıda benzer şekilde davrandılar. İki JOINS ve bir alt sorgu içeren karmaşık sorgu olan karşılaştırmalı son sorgu türü, alt belgelerin kullanımı nedeniyle MongoDB'nin MySQL üzerinde avantajını gösterdi. Bu avantaj, veritabanı boyutunda bir artışa neden olan veri çoğaltma maliyetiyle gelir. Bir uygulamada bu tür sorgular tipikse, daha büyük veritabanı boyutundan kaynaklanan depolama maliyetini ve bellek boyutunu dikkate alırken NoSQL veritabanlarını alternatif olarak düşünmek önemlidir.


-6

Tek Sunucuda MongoDb, hem okuma hem de yazmada mysql MyISAM'den daha hızlı olmaz, çünkü tablo / doc boyutları 1 GB ila 20 GB arasında küçüktür.
MonoDB, Mysql'nin yatay olarak ölçeklendirilemediği Çok Düğümlü kümelerde Paralel Azaltma konusunda daha hızlı olacaktır.


5
Bunu desteklemek için biraz kanıt veya daha fazla ayrıntı verebilir misiniz?
Steve Westbrook

Yatay olarak ölçeklenemiyor mu? NDB ne olacak? DRBD MySQL'i destekledi mi?
Ernestas

Bu doğru değil. MongoDB'nin 16MD belge limiti vardır. Mysql isterseniz çok daha fazla olabilir
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.