获取更多资料请公众号回复资料获取更多。
项目中有个接口,响应时间一直保持在3~4s左右。因为还要其他项目使用,其他项目的响应时间在5s以上,最近公司做了优化,超过5s的响应自动排除,所以说这个接口基本就是没用了。
我查看了接口。两次查询mogoDB的操作,一次请求另一个接口得操作。其他没用IO操作了。但是为什么会这么慢那,经过排查,请求接口得时间在1s以内,那么时间都在两次查询操作上,那么久排查查询操作。一次查询大约0.1s左右,一次查询在1s以上。
后来想到索引问题,耗费1s查询的没有建立所以。数据量大。那么找到问题就去解决,找了DBA加了索引,观察监控,接口响应时间由原来的3-4秒保持在了1s一下。两次查询总耗时0.1~0.2秒左右。那么为什么索引对查询影响这么大那?
为什么能够提高查询速度?
索引就是通过事先排好序,从而在查找时可以应用二分查找等高效率的算法。
一般的顺序查找,复杂度为O(n),而二分查找复杂度为O(log2n)。当n很大时,二者的效率相差及其悬殊。
举个例子:
表中有一百万条数据,需要在其中寻找一条特定id的数据。如果顺序查找,平均需要查找50万条数据。而用二分法,至多不超过20次就能找到。二者的效率差了2.5万倍!
在一个或者一些字段需要频繁用作查询条件,并且表数据较多的时候,创建索引会明显提高查询速度,因为可由全表扫描改成索引扫描。
(无索引时全表扫描也就是要逐条扫描全部记录,直到找完符合条件的,索引扫描可以直接定位)
不管数据表有无索引,首先在SGA的数据缓冲区中查找所需要的数据,如果数据缓冲区中没有需要的数据时,服务器进程才去读磁盘。
1、无索引,直接去读表数据存放的磁盘块,读到数据缓冲区中再查找需要的数据。
2、有索引,先读入索引表,通过索引表直接找到所需数据的物理地址,并把数据读入数据缓冲区中
索引有什么副作用吗?
·索引是有大量数据的时候才建立的,没有大量数据反而会浪费时间,因为索引是使用二叉树建立.
·当一个系统查询比较频繁,而新建,修改等操作比较少时,可以创建索引,这样查询的速度会比以前快很多,同时也带来弊端,就是新建或修改等操作时,比没有索引或没有建立覆盖索引时的要慢。
·索引并不是越多越好,太多索引会占用很多的索引表空间,甚至比存储一条记录更多。
对于需要频繁新增记录的表,最好不要创建索引,没有索引的表,执行insert、append都很快,有了索引以后,会多一个维护索引的操作,一些大表可能导致insert 速度非常慢。
所以,建索引需要慎重考虑,要根据实际情况来。
索引怎么创建?
MYSQL:
1.PRIMARY KEY(主键索引)
mysql>ALTER TABLE `table_name` ADD PRIMARY KEY( `column` )
2.UNIQUE(唯一索引)
mysql>ALTER TABLE `table_name` ADD UNIQUE(`column` )
3.INDEX(普通索引)
mysql>ALTER TABLE `table_name` ADD INDEXindex_name ( `column` )
4.FULLTEXT(全文索引)
mysql>ALTER TABLE `table_name` ADD FULLTEXT( `column` )
5.多列索引
mysql>ALTER TABLE `table_name` ADD INDEXindex_name( `column1`, `column2`, `column3` )
mogoDB:
创建索引ensureIndex()
MongoDB创建索引使用ensureIndex()方法。
语法结构
db.COLLECTION_NAME.ensureIndex(keys[,options])
·keys,要建立索引的参数列表。如:,其中key表示字 段 名,1表示升序排序,也可使用使用数字-1降序。
·options,可选参数,表示建立索引的设置。可选值如下:
·background,Boolean,在后台建立索引,以便建立索引时不阻止其他数据库活动。默认值 false。
·unique,Boolean,创建唯一索引。默认值 false。
·name,String,指定索引的名称。如果未指定,MongoDB会生成一个索引字段的名称和排序顺序串联。
·dropDups,Boolean,创建唯一索引时,如果出现重复删除后续出现的相同索引,只保留第一个。
·sparse,Boolean,对文档中不存在的字段数据不启用索引。默认值是 false。
·v,indexversion,索引的版本号。
·weights,document,索引权重值,数值在 1 到 99,999 之间,表示该索引相对于其他索引字段的得分权重。
如,为集合sites建立索引:
{
"createdCollectionAutomatically" :false,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1
}
注意:1.8版本之前创建索引使用createIndex(),1.8版本之后已移除该方法
ORACLE:
CREATE INDEX命令语法:
CREATE INDEX
CREATE [unique] INDEX [user.]index
ON [user.]table (column [ASC | DESC] [,column
[ASC | DESC] ] ... )
[CLUSTER [scheam.]cluster]
[INITRANS n]
[MAXTRANS n]
[PCTFREE n]
[STORAGE storage]
[TABLESPACE tablespace]
[NO SORT]
Advanced
其中:
schema ORACLE模式,缺省即为当前帐户
index 索引名
table 创建索引的基表名
column 基表中的列名,一个索引最多有16列,long列、long raw
列不能建索引列
DESC、ASC 缺省为ASC即升序排序
CLUSTER 指定一个聚簇(Hash cluster不能建索引)
INITRANS、MAXTRANS 指定初始和最大事务入口数
Tablespace 表空间名
STORAGE 存储参数,同create table 中的storage.
PCTFREE 索引数据块空闲空间的百分比(不能指定pctused)
NOSORT 不(能)排序(存储时就已按升序,所以指出不再排序)
领取专属 10元无门槛券
私享最新 技术干货