ใน MongoDB ฉันใช้แบบสอบถามขนาดใหญ่ ฉันจะสร้างดัชนีผสมหรือดัชนีเดี่ยวได้อย่างไร ดังนั้นเวลาตอบสนองของฉันจึงเพิ่มขึ้น

ในโครงการของฉัน ฉันมีคอลเลกชันโพสต์และนี่คือโครงร่าง:

posts:{
        title:            {type: String, required: false},
        text:             {type: String, required: false},
        plainDescription: {type: String, required: false},
        isBlog:           {type: Boolean,default: false},
        type:             {type: String, required: true, default:'USER', enum:["USER","GROUP"]},
        information:{
            tags:[],
            users:[],
            groups:[],
            likes:[],
            likesCount:   {type: Number, default: 0},           
            dislikes:[],
            dislikesCount:{type: Number, default: 0},
            spams:[],
            spamsCount:   {type: Number, default: 0},
            shares:[],
            sharesCount:  {type: Number, default: 0},
            comments:[],
            commentsCount:{type: Number, default: 0},
            reply:[],
            favorite: [],
            favoriteCount:{type: Number, default: 0},
            replyCount:   {type: Number, default: 0}
        },
        authorId            : { type: String, required: true},// Can be user Id or Group Id
        authorName          : { type: String, required: false},
        isReply             : { type: Boolean, default: false},
        replyOf             : { type: String, default: "",nullable: true, references: 'posts._id'},
        isQuoteReyell       : { type: Boolean, default: false},
        quoteReyellOf       : { type: String, default: "",nullable: true, references: 'posts._id'},
        createdAt           : { type: Date, default: Date.now},
        createdBy           : { type: String, required: false, references: 'users._id'},
        creatorName         : { type: String, required: true, references: 'users.userName'},
        updatedAt           : { type: Date, required: false,default: Date.now},
        updatedBy           : { type: String, required: false, references: 'users._id'},
        updatorName         : { type: String, required: false, references: 'users.userName'},
        publishedAt         : { type: Date, required: false},
        isBlockedByAdmin    : {type:  Boolean,default: false},
        isDelete            : {type:  Boolean,default: false},
        isRss               : {type:  Boolean,default: false},
        updatedObj          : [],
        sportName           : {type: String, default: ''},
        teamObj             : []
    },

และ ตามความต้องการของฉัน นี่คือแบบสอบถาม:

[{"$match":{"$and":[{"$or":[{"$and":[{"createdBy":{"$in":["5754c557bd961f3751ddd830"]}},{"createdAt":{"$lt":"2017-10-26T06:17:32.533Z"}},{"information.shares":{"$elemMatch":{"userId":{"$in":["5754c557bd961f3751ddd830"]},"sharedAt":{"$not":{"$gt":"2017-10-26T06:17:32.533Z"}}}}}]},{"$and":[{"isQuoteReyell":{"$ne":true}},{"updatedObj":{"$elemMatch":{"userId":{"$in":["5754c557bd961f3751ddd830"]},"type":"reyell","updatedAt":{"$not":{"$gt":"2017-10-26T06:17:32.533Z"}}}}},{"isReply":false}]},{"$and":[{"information.shares":{"$elemMatch":{"userId":{"$in":["5754c557bd961f3751ddd830"]},"sharedAt":{"$not":{"$gt":"2017-10-26T06:17:32.533Z"}}}}}]},{"$and":[{"isReply":true},{"createdBy":{"$in":["5754c557bd961f3751ddd830"]}},{"updatedAt":{"$lt":"2017-10-26T06:17:32.533Z"}}]},{"$and":[{"updatedObj":{"$elemMatch":{"userId":{"$in":["5754c557bd961f3751ddd830"]},"type":{"$ne":"reyell"},"updatedAt":{"$not":{"$gt":"2017-10-26T06:17:32.533Z"}}}}}]},{"$and":[{"createdBy":{"$in":["5754c557bd961f3751ddd830"]}},{"createdAt":{"$lt":"2017-10-26T06:17:32.533Z"}},{"isBlog":false},{"information.shares":{"$elemMatch":{"userId":{"$in":["5754c557bd961f3751ddd830"]},"sharedAt":{"$not":{"$gt":"2017-10-26T06:17:32.533Z"}}}}}]},{"$and":[{"isQuoteReyell":{"$ne":true}},{"updatedObj":{"$elemMatch":{"userId":{"$in":["5754c557bd961f3751ddd830"]},"type":"reyell","updatedAt":{"$not":{"$gt":"2017-10-26T06:17:32.533Z"}}}}},{"isReply":false}]},{"information.shares":{"$elemMatch":{"userId":{"$in":["5754c557bd961f3751ddd830"]},"sharedAt":{"$not":{"$gt":"2017-10-26T06:17:32.533Z"}}}}},{"$and":[{"isReply":true},{"createdBy":{"$in":["5754c557bd961f3751ddd830"]}},{"updatedAt":{"$lt":"2017-10-26T06:17:32.533Z"}},{"information.shares":{"$elemMatch":{"userId":{"$in":["5754c557bd961f3751ddd830"]},"sharedAt":{"$not":{"$gt":"2017-10-26T06:17:32.533Z"}}}}}]},{"$and":[{"information.shares":{"$elemMatch":{"userId":{"$in":["5754c557bd961f3751ddd830"]},"sharedAt":{"$not":{"$gt":"2017-10-26T06:17:32.533Z"}}}}},{"updatedObj":{"$elemMatch":{"userId":{"$in":["5754c557bd961f3751ddd830"]},"type":{"$ne":"reyell"},"updatedAt":{"$not":{"$gt":"2017-10-26T06:17:32.533Z"}}}}}]}]},{"isBlockedByAdmin":false},{"isDelete":false}]}},{"$unwind":"$updatedObj"},{"$match":{"$or":[{"$and":[{"updatedObj.type":"reyell"},{"updatedObj.userId":{"$in":["5754c557bd961f3751ddd830"]}}]},{"$and":[{"updatedObj.type":"create"}]}]}},{"$group":{"_id":"$_id","updated":{"$last":"$updatedObj"},"post":{"$last":"$$ROOT"}}},{"$sort":{"updated.updatedAt":-1}},{"$limit":15}]

ช่วยผมหน่อยนะครับว่าควรสร้างดัชนีหรือดัชนีผสมคอลัมน์ไหนครับจะได้ช่วยเพิ่มเวลาตอบสนองได้


person Nitesh    schedule 26.10.2017    source แหล่งที่มา


คำตอบ (1)


โดยทั่วไป คุณจะต้องวางดัชนีลงในฟิลด์ที่ใช้มากที่สุดเป็นเกณฑ์การกรองในการสืบค้นที่สำคัญที่สุด/บ่อยที่สุดของคุณ โดยเริ่มจากฟิลด์ที่เลือกมากที่สุดก่อน มีคำแนะนำที่เหมาะสมในหัวข้อนี้ค่อนข้างดี ซึ่งเป็นส่วนหนึ่งของเอกสารประกอบ MongoDB ข้อความหนึ่งที่น่าสนใจเป็นพิเศษสำหรับกรณีของคุณน่าจะเป็นเช่นนี้เนื่องจากคุณมี $ors จำนวนมาก:

โดยทั่วไปแล้ว MongoDB จะใช้เพียงดัชนีเดียวเพื่อตอบแบบสอบถามส่วนใหญ่ อย่างไรก็ตาม แต่ละคำสั่งของ $or แบบสอบถามอาจใช้ดัชนีที่แตกต่างกัน และตั้งแต่เวอร์ชัน 2.6 เป็นต้นไป MongoDB สามารถใช้จุดตัดของดัชนีหลายดัชนีได้

อย่างไรก็ตาม สิ่งที่สำคัญที่สุดที่นี่คือการวัด วัด วัดผล และดูแผนการดำเนินการค้นหาโดยใช้ อธิบาย() เหตุผลที่เป็นไปได้มากว่าคุณจะมีคำถามประเภทต่างๆ ที่แอปพลิเคชันของคุณต้องรองรับ และคุณจะต้องทำการแลกเปลี่ยน ณ จุดหนึ่งซึ่งคุณต้องเลือกระหว่างต้นทุนการบำรุงรักษาดัชนี (เช่น ล็อคการเขียน ระหว่างการอัปเดตดัชนีและข้อกำหนดพื้นที่ดิสก์) และในทางทฤษฎี วิธีแก้ปัญหาที่เร็วที่สุดโดยที่ทุกฟิลด์ที่ใช้ในแบบสอบถามเดียวถูกครอบคลุมโดยดัชนีเดียว

หัวข้อการจัดทำดัชนีทั้งหมดนั้นค่อนข้างคลุมเครือซึ่งขึ้นอยู่กับสถานการณ์ที่แน่นอนของคุณเป็นอย่างมาก:

  • ข้อมูลของคุณอัปเดตอย่างหนักและการเขียนจำเป็นต้องเร็วมาก (คุณจะต้องการดัชนีน้อยลง/เล็กลง) หรือข้อมูลของคุณค่อนข้างเสถียรด้วยการอ่านบ่อยครั้งที่ต้องเร็ว (ใช้ดัชนีมากขึ้น/ใหญ่กว่า)
  • คุณต้องการสนับสนุนคำค้นหาประเภทใดบ้าง มีความคล้ายคลึงกันเพียงใดในแง่ของตัวกรอง การใช้ตัวกรองร่วมกันบางรายการจะมีโอกาสมากกว่าตัวกรองอื่นๆ หรือไม่ คำค้นหาใดที่ต้องทำงานได้ดี คำค้นหาใดที่อาจช้ากว่าเล็กน้อย
  • ข้อมูลในช่องที่อาจจัดทำดัชนีของคุณมีการกระจายอย่างไร
  • และอื่นๆ...

คุณจะไม่พบดัชนีเดียวที่ช่วยให้การค้นหาทั้งหมดของคุณทำงานได้ดีที่สุด นอกจากนี้ เมื่อเพิ่มดัชนีเพิ่มเติมหรือเปลี่ยนแปลงดัชนีที่มีอยู่ สิ่งนี้อาจทำให้เครื่องมือเพิ่มประสิทธิภาพแบบสอบถามหยุดใช้ดัชนีบางส่วนสำหรับแบบสอบถามบางรายการ และเลือกแผนการดำเนินการอื่นแทน ซึ่งอาจหรือไม่ต้องการก็ได้ ดังนั้นวัดทุกสิ่งที่สำคัญเมื่อมีการเปลี่ยนแปลงในการจัดทำดัชนีหรือเค้าโครงข้อมูลทางกายภาพของคุณ (การตั้งค่าฮาร์ดแวร์ การแบ่งส่วน...) สุดท้ายนี้ คุณควรวัดประสิทธิภาพการสืบค้นของคุณเป็นประจำเมื่อปริมาณข้อมูลของคุณเพิ่มขึ้น เว้นแต่ว่าการกระจายข้อมูลจะมีความสม่ำเสมอที่คาดการณ์ได้

หากต้องการตัดเรื่องสั้นให้สั้นลง: ลองใช้แนวทางวนซ้ำและเริ่มต้นด้วยการเพิ่มดัชนี (ฉันขอแนะนำให้เพิ่มดัชนีใน isBlockedByAdmin, isDelete และ information.shares.userId) จากนั้นวัดประสิทธิภาพการค้นหาของคุณ จากนั้นปรับแต่งดัชนีตามสิ่งที่คุณค้นพบ (และอีกครั้ง และอีกครั้ง, ...).

person dnickless    schedule 26.10.2017