ประสิทธิภาพของ MongoDB เทียบกับ PostgreSQL 5.5 ล้านแถว / เอกสาร


10

บางคนสามารถช่วยฉันเปรียบเทียบคิวรีเหล่านี้และอธิบายว่าทำไมเคียวรี PostgreSQL ดำเนินการในเวลาไม่เกิน 2000 มิลลิวินาทีและคิวรีการรวม MongoDB ใช้เวลาเกือบ 9000 มิลลิวินาทีและบางครั้งสูงถึง 130K มิลลิวินาที

PostgreSQL 9.3.2 on x86_64-apple-darwin, compiled by i686-apple-darwin11-llvm-gcc-4.2 (GCC) 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.9.00), 64-bit

แบบสอบถาม PostgreSQL

SELECT locomotive_id,
   SUM(date_trunc('second', datetime) - date_trunc('second', prevDatetime)) AS utilization_time

FROM bpkdmp 
WHERE datetime >= '2013-7-26 00:00:00.0000' 
AND   datetime <= '2013-7-26 23:59:59.9999'
GROUP BY locomotive_id
order by locomotive_id

แบบสอบถาม MongoDB

db.bpkdmp.aggregate([
   {
      $match : {
          datetime : { $gte : new Date(2013,6,26, 0, 0, 0, 0), $lt : new Date(2013,6,26, 23, 59, 59, 9999) }
   }
   },
   {
      $project: {
         locomotive_id : "$locomotive_id",
         loco_time : { $subtract : ["$datetime", "$prevdatetime"] }, 
      }
   },
   {
      $group : {
         _id : "$locomotive_id",
         utilization_time : { $sum : "$loco_time" }
      }
   },
   {
      $sort : {_id : 1}
   }
])

ทั้งตาราง PostgreSQL และคอลเลกชัน MongoDB จะได้รับการสร้างดัชนีในวันที่และเวลา: 1 และ locomotive_id: 1

ข้อความค้นหาเหล่านี้กำลังทำการทดสอบบน iMac ด้วยไดรฟ์ไฮบริด 2TB และหน่วยความจำ 16GB ฉันได้รับผลลัพธ์ที่เทียบเท่าบนเครื่อง Windows 7 ที่มีหน่วยความจำ 8GB และ 256GB SSD

ขอบคุณ!

** อัปเดต: ฉันโพสต์ผลลัพธ์ EXPLAIN (BUFFERS, ANALYZE) หลังจากที่โพสต์คำถาม

"Sort  (cost=146036.84..146036.88 rows=19 width=24) (actual time=2182.443..2182.457 rows=152 loops=1)"
"  Sort Key: locomotive_id"
"  Sort Method: quicksort  Memory: 36kB"
"  Buffers: shared hit=13095"
"  ->  HashAggregate  (cost=146036.24..146036.43 rows=19 width=24) (actual time=2182.144..2182.360 rows=152 loops=1)"
"        Buffers: shared hit=13095"
"        ->  Bitmap Heap Scan on bpkdmp  (cost=12393.84..138736.97 rows=583942 width=24) (actual time=130.409..241.087 rows=559529 loops=1)"
"              Recheck Cond: ((datetime >= '2013-07-26 00:00:00'::timestamp without time zone) AND (datetime <= '2013-07-26 23:59:59.9999'::timestamp without time zone))"
"              Buffers: shared hit=13095"
"              ->  Bitmap Index Scan on bpkdmp_datetime_ix  (cost=0.00..12247.85 rows=583942 width=0) (actual time=127.707..127.707 rows=559529 loops=1)"
"                    Index Cond: ((datetime >= '2013-07-26 00:00:00'::timestamp without time zone) AND (datetime <= '2013-07-26 23:59:59.9999'::timestamp without time zone))"
"                    Buffers: shared hit=1531"
"Total runtime: 2182.620 ms"

** อัปเดต: Mongo อธิบาย:

อธิบายจาก MongoDB

{
"serverPipeline" : [
    {
        "query" : {
            "datetime" : {
                "$gte" : ISODate("2013-07-26T04:00:00Z"),
                "$lt" : ISODate("2013-07-27T04:00:08.999Z")
            }
        },
        "projection" : {
            "datetime" : 1,
            "locomotive_id" : 1,
            "prevdatetime" : 1,
            "_id" : 1
        },
        "cursor" : {
            "cursor" : "BtreeCursor datetime_1",
            "isMultiKey" : false,
            "n" : 559572,
            "nscannedObjects" : 559572,
            "nscanned" : 559572,
            "nscannedObjectsAllPlans" : 559572,
            "nscannedAllPlans" : 559572,
            "scanAndOrder" : false,
            "indexOnly" : false,
            "nYields" : 1,
            "nChunkSkips" : 0,
            "millis" : 988,
            "indexBounds" : {
                "datetime" : [
                    [
                        ISODate("2013-07-26T04:00:00Z"),
                        ISODate("2013-07-27T04:00:08.999Z")
                    ]
                ]
            },
            "allPlans" : [
                {
                    "cursor" : "BtreeCursor datetime_1",
                    "n" : 559572,
                    "nscannedObjects" : 559572,
                    "nscanned" : 559572,
                    "indexBounds" : {
                        "datetime" : [
                            [
                                ISODate("2013-07-26T04:00:00Z"),
                                ISODate("2013-07-27T04:00:08.999Z")
                            ]
                        ]
                    }
                }
            ],
            "oldPlan" : {
                "cursor" : "BtreeCursor datetime_1",
                "indexBounds" : {
                    "datetime" : [
                        [
                            ISODate("2013-07-26T04:00:00Z"),
                            ISODate("2013-07-27T04:00:08.999Z")
                        ]
                    ]
                }
            },
            "server" : "Michaels-iMac.local:27017"
        }
    },
    {
        "$project" : {
            "locomotive_id" : "$locomotive_id",
            "loco_time" : {
                "$subtract" : [
                    "$datetime",
                    "$prevdatetime"
                ]
            }
        }
    },
    {
        "$group" : {
            "_id" : "$locomotive_id",
            "utilization_time" : {
                "$sum" : "$loco_time"
            }
        }
    },
    {
        "$sort" : {
            "sortKey" : {
                "_id" : 1
            }
        }
    }
],
"ok" : 1
}

1
สำหรับEXPLAIN (BUFFERS, ANALYZE)ผลลัพธ์การค้นหาแบบสอบถามของ PostgreSQL โปรด นอกจากนี้เวอร์ชัน PostgreSQL (ฉันโหวตให้ย้ายไปที่ dba.SE)
Craig Ringer

... และข้อมูลเกี่ยวกับแผน MongoDB? docs.mongodb.org/manual/reference/method/cursor.explain
Craig Ringer

2
แม้ว่ามันจะยากที่จะหนีจาก NoSQL hype แต่ทว่า RDBMS แบบดั้งเดิมนั้นดีกว่าและมีการรวมกันมากขึ้นทุกวัน ฐานข้อมูล NoSQL ได้รับการปรับให้เหมาะสมสำหรับการจัดทำดัชนีและดึงข้อมูลคีย์หลักโดยใช้คีย์และไม่ใช่สำหรับการสืบค้น
Alexandros

ฉันอาจจะทิ้งรายละเอียดเล็กน้อย มีเอกสารมากกว่า 200 รายการในแต่ละเอกสาร นี่เป็นการนำเข้าโดยตรงจากฐานข้อมูล PostgreSQL ค่าฟิลด์จำนวนมากเป็นโมฆะ ฉันจำได้ว่า MongoDB ไม่ชอบค่า null เป็นพิเศษ ฉันได้นำเข้าอีกครั้งโดยมี <20 ฟิลด์ของข้อมูลที่เกี่ยวข้องและประสิทธิภาพการสืบค้นดีกว่า ฉันกำลัง <3000ms บนเครื่องที่มีหน่วยความจำ 8GB และ HD ที่ช้ากว่า ฉันจะเริ่มการทดสอบใหม่กับเครื่องจักรที่ทรงพลังกว่านี้เร็ว ๆ นี้
Mike A

ดัชนี Mongodb {datetime: 1, prevdatetime: 1}ควรทำงานได้ดีกว่าดัชนีปัจจุบันเนื่องจากตัวกรอง mongodb ในวันที่และเวลา มันจะลดจำนวนเอกสารที่ต้องสแกน
rubish

คำตอบ:


8

ทั้งหมด PostgreSQL จะทำที่นี่เป็นบิตแมปกองสแกนบนเพื่อค้นหาบล็อกที่อาจจะมีการจับคู่แถวแล้วสแกนกองของบล็อกที่จะหาที่ตรงกับแถวในbpkdmp_datetime_ix bpkdmpจากนั้นจัดกลุ่มแถวลงในที่เก็บแฮชโดยใช้แฮชของคีย์การจัดกลุ่มผลรวมแต่ละที่ฝากข้อมูลและเรียงลำดับผลลัพธ์ มันเป็นแผนแบบสอบถามพื้นฐานที่เรียบง่าย - มันอาจทำงานได้ดีขึ้นถ้าคุณทุ่มwork_memมันเยอะ แต่มันก็อาจจะไม่เหมือนกัน

ในแบบสอบถามนั้นไม่มีการขนานกันเช่นกัน ทุกอย่างจะเกิดขึ้นในแกนเดียว

ฉันสามารถสันนิษฐานได้ว่า MongoDB ใช้วิธีที่มีประสิทธิภาพน้อยกว่าหรือไม่ได้ประโยชน์จากดัชนีที่เหมาะสม คุณจะต้องแสดงexplainข้อความค้นหา MongoDB เพื่อแสดงความคิดเห็นที่เป็นประโยชน์ เห็นcursor.explainไหม

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.