避免mongo shell的查詢掃表問題

2021-09-19 20:07:24 字數 2830 閱讀 3508

mongodb資料庫的查詢基於索引的匹配,當乙個查詢事件沒有匹配索引的時候就會掃瞄整個collection的所有文件,導致效率非常低下,如下:

測試使用的乙個使用者表,5161條資料,可以看到有pid的索引,沒有login_account的索引

>db.persons.getindexes()[,

"name" : "_id_",

"ns" : "roster.persons"},,

"name" : "did_1_pid_1",

"ns" : "roster.persons",

"background" : true},,

"name" : "pid_1",

"ns" : "roster.persons",

"background" : true

}]

>db.persons.find(,)

>db.persons.find(,)

>db.persons.find(,).explain('allplan***ecution')

,...............

}>db.persons.find(,).explain('allplan***ecution')

,..............

}

可以明顯看出匹配索引的查詢很快處理,只需要讀乙個文件,但是沒有匹配索引的會掃瞄整個表得所有文件,雖然這裡看到時間相差不大,但當乙個表達到上億的時候,一次非匹配索引的查詢會讓整個資料庫卡死,線上資料庫做一些異常資料查詢的操作時候,還可能導致業務雪崩。可能會說都匹配索引的時候就好了?但是誰能保證每次都敲的命令沒有問題呢,比如上面查詢pid的時候,我敲錯了乙個字母變成了aid:

>db.persons.find(,).explain('allplan***ecution')

,.......

}

也會變成掃瞄整個表,導致效能急劇下降,另外這個掃瞄事件不太好中斷(ctrl+c是無法結束的,mongo資料庫還是會繼續執行這條命令,具體的結束方案另外再論)。

**路勁 mongo-3.2/srv/shell/collection.js,shell是客戶端工具的**路勁,collection.js是表的操作合集,find,findone,count等都是通過find查詢,所以我們在find函式這裡加上乙個對查詢條件匹配索引的校驗,具體**如下:

dbcollection.prototype.__checkindexesmatch = function(query) 

var count = this.count(null, null);

if (count < 1000)

var indexes = this.getindexes(null, null); //獲取所有的索引

var maxmatch = 0;

//遍歷索引,看是否都是否查詢條件裡面是不是能匹配上索引

for (var index in indexes) else

}if (maxmatch < match)

}// 最少要匹配乙個索引字段,否則不予查詢,這裡索引匹配度可以自行定義

if (maxmatch > 0)

return false;

}dbcollection.prototype.find = function(query, fields, limit, skip, batchsize, options)

var cursor = new dbquery(this._mongo,

this._db,

this,

this._fullname,

this._massageobject(query),

fields,

limit,

skip,

batchsize,

options || this.getqueryoptions());

var connobj = this.getmongo();

var readprefmode = connobj.getreadprefmode();

if (readprefmode != null)

return cursor;

};

其中__checkindexesmatch()是新增的函式,修改好後編譯成mongo客戶端(具體的編譯方法,本文不做描述,可以參考),替換後我們再次執行異常查詢效果如下:

> db.persons.find(,)

2019-03-14t20:16:12.410+0800 e query [thread1] error: find not match indexes ! please use original mongo!!! :

dbcollection.prototype.find@src/mongo/shell/collection.js:301:1

@(shell):1:1

> db.persons.find(,)

2019-03-14t20:16:30.836+0800 e query [thread1] error: find not match indexes ! please use original mongo!!! :

dbcollection.prototype.find@src/mongo/shell/collection.js:301:1

@(shell):1:1

> db.persons.find(,)

可以看到前倆個不匹配索引導致低效的查詢會被拒絕,從而達到線上資料庫查詢維護的時候不會因為敲錯命令導致整個伺服器雪崩。

mongo shell中特殊判斷符號轉義的問題

root mongo bash x t.sh usr local mongodb bin mongo 127.0.0.1 37017 test uadmin padmin quiet eval printjson db.tickets.findone fri apr 26 15 32 49 synt...

模糊查詢的時候避免索引失效

有時候我們使用模糊查詢 like 的時候,會出現索引失效的情況,比如根據手機號碼後四位模糊匹配查詢。在mysql中模糊查詢 mobile like 8765 這種情況是不能使用 mobile 上的索引的,那麼如果需要根據手機號碼後四位進行模糊查詢,可以用一下方法進行改造。我們可以加入冗餘列 mysq...

oracle引數查詢避免SQL注入

前言。所謂sql注入,就是通過把sql命令插入到web 表單提交或輸入網域名稱或頁面請求的查詢字串,最終達到欺騙伺服器執行惡意的sql命令。具體來說,它是利用現有應用程式,將 惡意的 sql命令注入到後台資料庫引擎執行的能力,它可以通過在web表單中輸入 惡意 sql語句得到乙個存在安全漏洞的 上的...