索引的定义和原理
数据库的索引,是一种将数据库中的特定数据进行排序化的数据结构,用以提高数据库的查询和变更效率。索引的实现通常使用B树或B+树。
比如,当前有一个表有100w条数据,表结构为如下create table person ( name char(15) not null, age int not null, city varchar(20) not null, primary key(name) )
主键是用户的name。假设用户居住的城市有限(比如100个),现在,如果要查询在city=“shanghai”的用户,那么如果没有索引的话,需要scan整个表,遍历100w次,并且匹配对应的city字段,如果city=“shanghai”则拿出来,效率非常低。如果对city字段创建了索引,由于city的值有限(100个),基于city的值build一个B树,那么如果想要查找city=“shanghai”的,基本上只需要log2(N),也就是最多9次,就能找到所有的city=“shanghai”的人了
不过,索引虽然能加快数据库的查询性能,但是需要额外占用空间用于存放索引数据,而且在插入和更新数据时效率也会变低(需要同时更新索引表)。因此索引表的创建,需要基于业务的实际情况进行,并不是索引表越多越好。
索引的类型
唯一索引
唯一索引能保证集合的每个文档的指定值都有唯一值,创建方式:
db.xxx.ensureIndex({"username":1},{"unique":true}
不过mongodb在insert的时候,并不会检查文档的唯一值,因此为了避免唯一键重复,需要使用安全插入,检查对应的getLastError 地理空间索引
用于查找地理位置上最近的点的索引,创建方式:
db.xxx.ensureIndex{"gps":"2d"}
gps必须是一对值,包含两个元素,以下形式都有效: {“gps”: [0, 100]}{"gps":{"x":0, "y":100}}
并且对应的字段可以自定义,不一定是x,y,查询的时候,可以基于whithin,center等选项进行查询
索引创建规则:
- 基于实际的查询场景创建索引,考虑需要哪些键,是否需要联合索引,每个键的索引方向是怎么样,等等
- 如果需要对集合进行排序,如果对没有索引的键调用sort,mongodb则会把所有数据都提取到内存中进行排序,对数据的大小是有限制的。因此建议对需要sort的数据合理设置索引
- 擅于利用explain来查看查询对应的索引使用情况
- 创建索引的时候,最好在后台创建(创建时指定background: true),否则,mongodb会阻塞所有请求,直到索引创建完毕