控えめに150万件以上と言ったけど実際は190万件ぐらいだった。
以下の全てのクエリは 0 件を返す。
というか今見たら $and
使う必要はなかった。
// 89790ms db.getCollection('colName').find({$and: [{name: /(あああ)/}, {status: 1}]}) // 1361ms db.getCollection('colName').find({$and: [{name: /^(あああ)/}, {status: 1}]}).hint({name: 1}) // 4ms db.getCollection('colName').find({$and: [{name: /^あああ/}, {status: 1}]}).hint({name: 1}) // 107386ms db.getCollection('colName').find({$and: [{name: /^(あああ)/}, {status: 1}]}) // 86117ms db.getCollection('colName').find({$and: [{name: /^あああ/}, {status: 1}]})
/(あああ)/
よりヒントなしの /^(あああ)/
が遅いのが謎。
ちなみに文字列検索した時は普通にインデックスが効くっぽいのですぐ返ってくる。
// 15ms db.getCollection('colName').find({$and: [{name: "あああ"}, {status: 1}]})
公式ドキュメント
- case insensitive なパターンを使うこと
^
や\A
で始めること- 先頭からのマッチの長さをなるべく短くする
- 例えば
/^a/
,/^a.*/
,/^a.*$/
だったら/^a/
が一番速い - [私見] 安易に
.*
とか書かずにどうしても必要なら non-greedy match にするといいかも (.*?
)
- 例えば
あとドキュメントに書いてないけど冒頭の結果から分かるのは
()
を使わない
もですかね。
TODO
$explain した結果も貼る。