find and update requests of different types. Thousands of such requests are received per second during peak hours.Mon Aug 2 10:34:24.928 I COMMAND [conn10480929] command xxx.xxx command: find { find: "xxx", filter: { $and: [ { alxxxId: "xxx" }, { state: 0 }, { itemTagList: { $in: [ xx ] } }, { persxxal: 0 } ] }, limit: 3, maxTimeMS: 10000 } planSummary: IXSCAN { alxxxId: 1.0, itemTagList: 1.0 } keysExamined:1650 docsExamined:1650 hasSortStage:0 cursorExhausted:1 keyUpdates:0 writeConflicts:0 numYields:15 nreturned:3 reslen:8129 locks:{ Global: { acquireCount: { r: 32 } }, Database: { acquireCount: { r: 16 } }, Collection: { acquireCount: { r: 16 } } } protocol:op_command 227msMon Aug 2 10:34:22.965 I COMMAND [conn10301893] command xx.txxx command: find { find: "txxitem", filter: { $and: [ { itxxxId: "xxxx" }, { state: 0 }, { itemTagList: { $in: [ xxx ] } }, { persxxal: 0 } ] }, limit: 3, maxTimeMS: 10000 } planSummary: IXSCAN { alxxxId: 1.0, itemTagList: 1.0 } keysExamined:1498 docsExamined:1498 hasSortStage:0 cursorExhausted:1 keyUpdates:0 writeConflicts:0 numYields:12 nreturned:3 reslen:8039 locks:{ Global: { acquireCount: { r: 26 } }, Database: { acquireCount: { r: 13 } }, Collection: { acquireCount: { r: 13 } } } protocol:op_command 158ms
{ alxxxId: 1.0, itemTagList: 1.0 } index. keysExamined and docsExamined are both set to 1498 for scan by index; however, the number of returned documents (nreturned) is only 3; that is, only 3 data entries out of the 1498 rows of data and indexes scanned meet the conditions. As can be seen, the key cause compromising the read/write performance is unreasonable index configuration.keysExamined and docsExamined indicate the numbers of index entries and documents scanned respectively. Larger keysExamined and docsExamined values indicate that no index is created or the created index is less distinctive.Query based on `AlxxxId` (user ID) and `itxxxId` (one or multiple values).`count` query based on `AlxxxId`.Paginated query based on `AlxxxId` by time range (`createTime`). In some queries, `state` and other fields will be concatenated.Query based on `AlxxxId`, `ParentAlxxxId`, `parentItxxxId`, and `state`.Query based on `ItxxxId` (one or multiple values).Query based on `AlxxxId`, `state`, and `updateTime`.Query based on `AlxxxId`, `state`, `createTime`, and `totalStock` (number of inventory items).Query based on `AlxxxId` (user ID), `itxxxId` (one or multiple values), and any other fields.Query based on `AlxxxId`, `digitalxxxrmarkId` (watermark ID), and `state`.Query based on `AlxxxId`, `itemTagList` (tag ID), and `state`.Query based on `AlxxxId`, `itxxxId` (one or multiple values), and any other fields.Other queries
Query based on `AlxxxId`, `state`, and `persxxal`.Query based on `AlxxxId`, `state`, and `itemType`.Query based on `AlxxxId` (user ID), `itxxxId` (one or multiple values), and any other fields.
db.xxx.getindex() to get the collection index information. The query is complex, and there are 30 indexes in total as listed below:{ "alxxxId" : 1, "state" : -1, "updateTime" : -1, "itxxxId" : -1, "persxxal" : 1, "srcItxxxId" : -1 }{ "alxxxId" : 1, "image" : 1 }{ "itexxxList.vidxxCheck" : 1, "itemType" : 1, "state" : 1 }{ "alxxxId" : 1, "state" : -1, "newsendTime" : -1, "itxxxId" : 1, "persxxal" : 1 }{ "_id" : 1 }{ "alxxxId" : 1, "createTime" : -1, "checkStatus" : 1 }{ "alxxxId" : 1, "parentItxxxId" : -1, "state" : -1, "updateTime" : -1, "persxxal" : 1, "srcItxxxId" : -1 }{ "alxxxId" : 1, "state" : -1, "parentItxxxId" : 1, "updateTime" : -1, "persxxal" : -1 }{ "srcItxxxId" : 1 }{ "createTime" : 1 }{ "itexxxList.boyunState" : -1, "itexxxList.wozhituUploadServerId": -1, "itexxxList.photoQiniuUrl" : 1, "itexxxList.sourceType" : 1 }{ "alxxxId" : 1, "state" : 1, "digitalxxxrmarkId" : 1, "updateTime" : -1 }{ "itxxxId" : -1 }{ "alxxxId" : 1, "parentItxxxId" : 1, "parentAlxxxId" : 1, "state" : 1 }{ "alxxxId" : 1, "videoCover" : 1 }{ "alxxxId" : 1, "itemType" : 1 }{ "alxxxId" : 1, "state" : -1, "itemType" : 1, "persxxal" : 1, "updateTime" : 1 }{ "alxxxId" : 1, "itxxxId" : 1 }{ "itxxxId" : 1, "alxxxId" : 1 }{ "alxxxId" : 1, "parentAlxxxId" : 1, "state" : 1 }{ "alxxxId" : 1, "itemTagList" : 1 }{ "itexxxList.photoQiniuUrl" : 1, "itexxxList.boyunState" : -1, "itexxxList.sourceType" : 1, "itexxxList.wozhituUploadServerId" : -1 }{ "alxxxId" : 1, "parentItxxxId" : 1, "state" : 1 }{ "alxxxId" : 1, "parentItxxxId" : 1, "updateTime" : 1 }{ "updateTime" : 1 }{ "itemPhoxxIdList" : -1 }{ "alxxxId" : 1, "state" : -1, "isTop" : 1 }{ "alxxxId" : 1, "state" : 1, "itemResxxxIdList" : 1, "updateTime" : -1 }{ "alxxxId" : 1, "state" : -1, "itexxxList.photoQiniuUrl" : 1 }{ "itexxxList.qiniuStatus" : 1, "itexxxList.photoNetUrl" : 1, "itexxxList.photoQiniuUrl" : 1 }{ "itemResxxxIdList" : 1 }
> db.xxxxx.aggregate({"$indexStats":{}}){ "name" : "alxxxId_1_parentItxxxId_1_parentAlxxxId_1", "key" : { "alxxxId" : 1, "parentItxxxId" : 1, "parentAlxxxId" : 1 },"host" : "TENCENT64.site:7014", "accesses" : { "ops" : NumberLong(11236765),"since" : ISODate("2020-08-17T06:39:43.840Z") } }
ops value smaller than 10,000 can also be deleted. At this point, 30 - 11 = 19 useful indexes are retained. db.xxx.aggregate({"$indexStats":{}}){ "alxxxId" : 1, "state" : -1, "updateTime" : -1, "itxxxId" : -1, "persxxal" : 1, "srcItxxxId" : -1 } "ops" : NumberLong(88518502){ "alxxxId" : 1, "image" : 1 } "ops" : NumberLong(293104){ "itexxxList.vidxxCheck" : 1, "itemType" : 1, "state" : 1 } "ops" : NumberLong(0){ "alxxxId" : 1, "state" : -1, "newsendTime" : -1, "itxxxId" : -1, "persxxal" : 1 } "ops" : NumberLong(33361216){ "_id" : 1 } "ops" : NumberLong(3987){ "alxxxId" : 1, "createTime" : 1, "checkStatus" : 1 } "ops" : NumberLong(20042796){ "alxxxId" : 1, "parentItxxxId" : -1, "state" : -1, "updateTime" : -1, "persxxal" : 1, "srcItxxxId" : -1 } "ops" : NumberLong(43042796){ "alxxxId" : 1, "state" : -1, "parentItxxxId" : 1, "updateTime" : -1, "persxxal" : -1 } "ops" : NumberLong(3042796){ "itxxxId" : -1 } "ops" : NumberLong(38854593){ "srcItxxxId" : -1 } "ops" : NumberLong(0){ "createTime" : 1 } "ops" : NumberLong(62){ "itexxxList.boyunState" : -1, "itexxxList.wozhituUploadServerId" : -1, "itexxxList.photoQiniuUrl" : 1, "itexxxList.sourceType" : 1 } "ops" : NumberLong(0){ "alxxxId" : 1, "state" : 1, "digitalxxxrmarkId" : 1, "updateTime" : -1 } "ops" : NumberLong(140238342){ "itxxxId" : -1 } "ops" : NumberLong(38854593){ "alxxxId" : 1, "parentItxxxId" : 1, "parentAlxxxId" : 1, "state" : 1 } "ops" : NumberLong(132237254){ "alxxxId" : 1, "videoCover" : 1 } { "ops" : NumberLong(2921857){ "alxxxId" : 1, "itemType" : 1 } { "ops" : NumberLong(457){ "alxxxId" : 1, "state" : -1, "itemType" : 1, "persxxal" : 1, " itxxxId " : 1 } "ops" : NumberLong(68730734){ "alxxxId" : 1, "itxxxId" : 1 } "ops" : NumberLong(232360252){ "itxxxId" : 1, "alxxxId" : 1 } "ops" : NumberLong(145640252){ "alxxxId" : 1, "parentAlxxxId" : 1, "state" : 1 } "ops" : NumberLong(689891){ "alxxxId" : 1, "itemTagList" : 1 } "ops" : NumberLong(2898693682){ "itexxxList.photoQiniuUrl" : 1, "itexxxList.boyunState" : 1, "itexxxList.sourceType" : 1, "itexxxList.wozhituUploadServerId" : 1 } "ops" : NumberLong(511303207){ "alxxxId" : 1, "parentItxxxId" : 1, "state" : 1 } "ops" : NumberLong(0){ "alxxxId" : 1, "parentItxxxId" : 1, "updateTime" : 1 } "ops" : NumberLong(0){ "updateTime" : 1 } "ops" : NumberLong(1397){ "itemPhoxxIdList" : -1 } "ops" : NumberLong(0){ "alxxxId" : 1, "state" : -1, "isTop" : 1 } "ops" : NumberLong(213305){ "alxxxId" : 1, "state" : 1, "itemResxxxIdList" : 1, "updateTime" : 1 } "ops" : NumberLong(2591780){ "alxxxId" : 1, "state" : 1, "itexxxList.photoQiniuUrl" : 1} "ops" : NumberLong(23505){ "itexxxList.qiniuStatus" : 1, "itexxxList.photoNetUrl" : 1, "itexxxList.photoQiniuUrl" : 1 } "ops" : NumberLong(0){ "itemResxxxIdList" : 1 } "ops" : NumberLong(7)
db.xxxx.find({{ "alxxxId" : xxx, "itxxxId" : xxx }})db.xxxx.find({{ " itxxxId " : xxx, " alxxxId " : xxx }})
{ itxxxId:1, alxxxId:1 } and { itxxxId :1} indexes, { itxxxId :1} is a duplicate. { "alxxxId" : 1, "parentItxxxId" : 1, "parentAlxxxId" : 1, "state" : 1 }{ "alxxxId" : 1, "parentAlxxxId" : 1, "state" : 1 }{ "alxxxId" : 1, " state " : 1 }
Db.xxx.find({ "alxxxId" : xxx, "parentItxxxId" : xx, "parentAlxxxId" : xxx, "state" : xxx })Db.xxx.find({ "alxxxId" : xxx, " parentAlxxxId " : xx, " state " : xxx })Db.xxx.find({ "alxxxId" : xxx, " state " : xxx })
{ "alxxxId" : 1, " state " : 1, " parentAlxxxId " : 1, parentItxxxId :1}
{ itxxxId:1, alxxxId:1 }{ "alxxxId" : 1, "parentItxxxId" : 1, "parentAlxxxId" : 1, "state" : 1 }
alxxxId and itxxxId fields are frequently used. By analyzing the schema information and extracting random data, you can find that the combination of these two fields are unique.
It is confirmed that any combination of the two fields represents a unique data entry. Therefore, all combinations of the two fields and any other fields are unique, and the following indexes can be combined into { itxxxId:1, alxxxId:1 }.{ "alxxxId" : 1, "state" : -1, "updateTime" : -1, "itxxxId" : 1, "persxxal" : 1, "srcItxxxId" : -1 }{ "alxxxId" : 1, "state" : -1, "itemType" : 1, "persxxal" : 1, " itxxxId " : 1 }{ "alxxxId" : 1, "state" : -1, "newsendTime" : -1, "itxxxId" : 1, "persxxal" : 1 }{ "alxxxId" : 1, "state" : 1, "itxxxId" : 1, "updateTime" : -1 }{ itxxxId:1, alxxxId:1 }
createTime and updateTime, which are used for various range queries. Range queries are non-equi queries. If range query fields are placed before index fields, index fields will fail to be indexed as shown below:db.collection.find({{ "alxxxId" : xx, "parentItxxxId" : xx, "state" : xx, "updateTime" : {$gt: xxxxx}, "persxxal" : xxx, "srcItxxxId" : xxx } })db.collection.find({{ "alxxxId" : xx, "state" : xx, "parentItxxxId" : xx, "updateTime" : {$lt: xxxxx}, "persxxal" : xxx} })
updateTime field and are range queries. Except the updateTime fields, all other fields are equi queries, and fields on the right of updateTime cannot use indexes; that is, the persxxal and srcItxxxId fields of the first index and the persxxal field of the second index cannot be matched with indexes. { "alxxxId" : 1, "parentItxxxId" : -1, "state" : -1, "updateTime" : -1, "persxxal" : 1, "srcItxxxId" : -1 }{ "alxxxId" : 1, "state" : -1, "parentItxxxId" : 1, "updateTime" : -1, "persxxal" : -1 }
{ "alxxxId" : 1, "state" : -1, "parentItxxxId" : 1, "persxxal" : -1, "updateTime" : -1 }
image and videoCover fields respectively as shown below:{ "alxxxId" : 1, "image" : 1 } "ops" : NumberLong(293104){ "alxxxId" : 1, "videoCover" : 1 } "ops" : NumberLong(292857)
Mon Aug 2 10:56:46.533 I COMMAND [conn5491176] command xxxx.tbxxxxx command: count { count: "xxxxx", query: { alxxxId: "xxxxxx", itxxxId: "xxxxx", image: "http:/xxxxxxxxxxx/xxxxx.jpg" }, limit: 1 } planSummary: IXSCAN { itxxxId: 1.0,alxxxId:1.0 } keyUpdates:0 writeConflicts:0 numYields:1 reslen:62 locks:{ Global: { acquireCount: { r: 4 } }, Database: { acquireCount: { r: 2 } }, Collection: { acquireCount: { r: 2 } } } protocol:op_query 4msMon Aug 2 10:47:53.262 I COMMAND [conn10428265] command xxxx.tbxxxxx command: find { find: "xxxxx", filter: { $and: [ { alxxxId: "xxxxxxx" }, { state: 0 }, { itemTagList: { $size: 0 } } ] }, limit: 1, singleBatch: true } planSummary: IXSCAN { alxxxId: 1, videoCover: 1 } keysExamined:128 docsExamined:128 cursorExhausted:1 keyUpdates:0 writeConflicts:0 numYields:22 nreturned:0 reslen:108 locks:{ Global:{ acquireCount: { r: 46 } }, Database: { acquireCount: { r: 23 } }, Collection: { acquireCount: { r: 23 } } } protocol:op_command 148ms
image field: It is used together with alxxxId and itxxxId for combined query. However, the combination of alxxxId and itxxxId is already unique, and the image field is totally not indexed, so the { "alxxxId" : 1, "ixxxge" : 1 } index can be deleted.videoCover field: By analyzing logs, it can be found that videoCover is not in the query conditions, only part of queries match the { alxxxId: 1, videoCover: 1 } index, and keysExamined and docsExamined are different from nreturned. Therefore, it can be confirmed that only the alxxxId index field is matched, and the { alxxxId: 1, videoCover: 1 } index can also be deleted.
Mon Aug 2 10:47:58.015 I COMMAND [conn4352017] command xxxx.xxx command: find { find: "xxxxx", filter: { $and: [ { alxxxId:"xxxxx" }, { state: 0 }, { itemTagList: { $in: [ xxxxx ] } }, { persxxal: 0 } ] }, projection: { $sortKey: { $meta: "sortKey" } }, sort: { updateTime: 1 }, limit: 3, maxTimeMS: 10000 } planSummary: IXSCAN { alxxxId: 1.0, itexxagList: 1.0 } keysExamined:1327 docsExamined:1327 hasSortStage:1 cursorExhausted:1 keyUpdates:0 writeConflicts:0 numYields:23 nreturned:3 reslen:12036 locks:{ Global: { acquireCount: { r: 48 } }, Database: { acquireCount: { r: 24 } }, Collection: { acquireCount: { r: 24 } } } protocol:op_command 151ms
{ alxxxId: 1.0, itexxagList: 1.0 } index, and there is a huge difference between the numbers of scanned data rows and returned rows: 1327 vs. 3.{ alxxxId: 1.0, itexxagList: 1.0 , persxxal:1.0, stat:1.0}.sort and a limit. Below is the entire raw query SQL statement:db.xxx.find({ $and: [ { alxxxId:"xxxx" }, { state: 0 }, { itexxagList: { $in: [ xxxx ] } },{ persxxal: 0 } ] }).sort({updateTime:1}).limit(3)
sort query, and limit, so the optimal index of the query can be one of the following two indexes: { $and: [ { alxxxId:"xxx" }, { state: 0 }, { itexxagList: { $in: [ xxxx ] } }, { persxxal: 0 } ] }
{ alxxxId: 1.0, itexxagList: 1.0 , persxxal:1.0, stat:1.0}
sort query, and limit is as detailed below:{ alxxxId: 1.0, itexxagList: 1.0 , persxxal:1.0, stat:1.0} index to find all data entries meeting the conditions specified by { $and: [ { alxxxId:"xxxx" }, { state: 0 }, { itexxagList: { $in: [ xxxx ] } }, { persxxal: 0 } ] }.sort
The sort query has a limit. Find the frequent sorting SQL statement, which is as shown below:{ $and: [ { alxxxId:"xxxx" }, { state: 0 }, { itexxagList: { $in: [ xxxx ] } }, { persxxal: 0 } ] }.sort({updateTime :1}).limit(10)
{ alxxxId: 1.0, itexxagList: 1.0 , persxxal:1.0, stat:1.0, updateTime : 1}
{ "itxxxId" : 1, "alxxxId" : 1 }{ "alxxxId" : 1, "state" : 1, "digitalxxxrmarkId" : 1, "updateTime" : 1 }{ "alxxxId" : 1, "state" : -1, "parentItxxxId" : 1, "persxxal" : -1, "updateTime" : 1 } { "alxxxId" : 1, "itexxxList.photoQiniuUrl" : 1, }{ "alxxxId" : 1, "parentAlxxxId" : 1, "state" : 1"parentItxxxId" : 1}{ alxxxId: 1.0, itexxagList: 1.0 , persxxal:1.0, stat:1.0, updateTime:1}{ "alxxxId" : 1, "createTime" : -1}
フィードバック