黑马程序员技术交流社区

标题: 【成都校区】数据库索引影响有多大? [打印本页]

作者: 小刀葛小伦    时间: 2019-8-8 16:22
标题: 【成都校区】数据库索引影响有多大?

项目中有个接口,响应时间一直保持在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 不(能)排序(存储时就已按升序,所以指出不再排序)







欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2