数据库查询性能优化之利器—索引(二)

简介:

     数据库查询性能优化之利器—索引(二)

  在前面一篇文章中谈到适当地建立索引能够大幅度地提升SQL语句查询速度,然而并不是在什么情况下都适合建立索引,下面来谈一下什么情况下适合建立索引、建立什么样的索引以及建立索引带来的好处和坏处。

一.索引的概念

  广义的索引是指:将具有检索意义的事项按照一定方式排列,以方便进行检索。数据库中的索引是指:将数据库表中的一列或者多列按照一定的方式进行组织以方便对数据库表中的内容进行查询。

  字典是广义的索引最好的例子,比如我们在字典中查找"陈"字,有两种查找方式:拼音查找和偏旁查找。拼音查找的前提是知道这个字的大概读音是"chen",然后去目录的拼音页列表查找到拼音为"chen"的汉字所在的页码,比如找到拼音为"chen"的汉字所在的起始页码为100,然后就会直接把字典翻到100页,如果该汉字恰好在100页,则查找到该汉字了,如果不在100页,那么继续往后面翻几页就会找到该汉字了。进行偏旁查找不需要知道该汉字的读音,只需要先在目录的偏旁列表中找到" 阝"对应的页码比如说12,然后去12页找到"陈"字所在的具体页码比如说101,最后只需要直接把字典翻到101页就可以看到"陈"字了。试想一下如果字典没有这个目录,要想在字典中找到某个汉字的话是很难的,最直接的办法可能就是从字典的正文第一页逐页查找直到找到该汉字为止,这个过程所耗费的时间是可想而知的,可能找一上午都找不到要找的汉字。

  数据库中的索引跟字典的目录类似。数据库文件中的内容是存储在磁盘上的,当在数据库中查找记录时,如果能获得该记录在磁盘上存储的位置,就能迅速找到该记录,就跟查找汉字一样,否则的话就只有对数据库表中的所有内容进行扫描,直到找到符合条件的记录为止,这样显然会消费很多的时间。因此适当地创建索引能够加快查询速度。比如,我有一张表

  peple( id integer(PK), name varchar(40) , age tinyint , tel varchar(20) )

  里面有若干条数据:

1 Tom 20 8544345
2 Mark 28 6789353
3 Jim 18 13945673456
4 Jack 20 8675456
5 Jemyy 12 6789456

  然后执行语句 select * from people where name='Jemyy';

  会对所有的数据记录进行扫描逐一进行条件匹配,直到找到符合条件的记录。如果在name列上建立了索引,与字典的目录进行类比,假如把name列按照字母升序进行排列,然后可能就得到一个目录:

Jack 第四条记录的存储位置
Jemyy 第五条记录的存储位置
Jim 第三条记录的存储位置
Mark 第二条记录的存储位置
Tom 第一条记录的存储位置

  查找的时候先找到Jemyy得到该记录的存储位置,然后根据存储位置获取该记录的内容。上面过程只是类比字典的查找对索引的一个理解,实际当中SQL利用索引进行查找的过程可能跟上面略有不同(没有研究过实际的SQL利用索引进行查找的过程,这个估计得需要读SQL引擎的源码),但是原理是类似的。

 二.索引的分类

  根据索引项与表中记录的物理顺序是否一致索引可以分为聚簇索引和非聚簇索引。索引项的顺序与表中记录的物理顺序一致的索引称作为聚簇索引,不一致的索引则称为非聚簇索引。比如字典的拼音查找目录就是聚簇索引,而偏旁查找目录则是非聚簇索引。

  根据索引包含的列的多少分为多列索引和单列索引,在创建索引的时候,可以选择在某一列上创建索引,也可以选择在多个列上创建索引。

    还有一种叫做唯一索引,表示此索引的每一个索引项对应一个唯一的数据记录。

  根据聚簇索引和非聚簇索引的概念可以知道,在一张表上只会有一个聚簇索引,因为一张表中的记录的物理顺序规则只有一种,而可以有多个非聚簇索引。

三.索引的创建

  在创建索引之前,要考虑好是否适合在某些列上创建索引,创建聚簇索引还是非聚簇索引,是创建单列索引还是多列索引,亦或是唯一索引。

  创建索引的SQL语句格式为:

create [unique][cluster|noncluster] index indexname on tablename([column asc|desc,column asc|desc..)

  在创建索引时,unique和cluster|noncluster以及asc|desc是可选的,当没有指定索引为唯一索引时,默认为非唯一索引;没有指定索引为聚簇索引还是非聚簇索引时,则默认为非聚簇索引;没有指定索引值的排序方式时,默认为asc升序。

  一般情况下来说,在经常需要进行搜索、进行外连接以及排序的列上比较适合建立索引,而很少使用到或者需要经常被修改的列上则不适合建立索引。建立索引虽然能够加快查询速度,但是同时也为数据库的维护带来了不便。由于要对索引进行存储,所以建立索引带来了额外的空间消耗;并且建立索引对数据库的修改造成了很大的不便,当要往数据库里插入数据或者修改数据时,索引也会随之自动进行修改,这个时候会带来很大的时间消耗。因此如果在一开始没考虑好,比如在需要经常修改的列上建立索引,后期的维护是很麻烦的。

  当需要返回某个范围内的值的时候,选择创建聚簇索引是比较合适的,就跟拼音查找类似,可以找到读音为"chen"的若干个汉字。

  而对于多列索引和单列索引的选择则一般需要根据where子句的判断条件来选择。比如:

select * from peple where name='jack'

  此时则适合在name列上建立单列索引,而

select * from peple where name='jack' and age>20

  此时则适合在name和age列上创建多列索引,这样更能够加快查询速度。索引的使用具有最左前缀匹配原则,当判别条件中存在索引的引导列时会使用该索引。假设people表有四个索引nameindex(name),ageindex(age),telindex(tel),mutilindex(name,age,tel)。

  select * from peple where name='jack' 会选择使用nameindex索引,而select * from peple where name='jack' and age>20则会选择使用mutilindex,注意一次查询只能使用上面4个索引中的一个索引。对于mutilindex,若判别条件为(name),(name,age),(name,age,tel),(name,tel)等都可以使用该索引,而(age,tel),(tel)都不能够使用该做引。

 

本文转载自海 子博客园博客,原文链接:http://www.cnblogs.com/dolphin0520/archive/2012/09/03/2659755.html如需转载自行联系原作者

相关文章
|
10天前
|
存储 机器学习/深度学习 搜索推荐
深入解析矢量数据库的数据模型与索引机制
【4月更文挑战第30天】本文深入探讨了矢量数据库的数据模型和索引机制。向量数据库以高维向量表示数据,采用稀疏或密集向量形式,并通过数据编码和组织优化存储与检索。索引机制包括基于树的(如KD-Tree和Ball Tree)、基于哈希的(LSH)和近似方法(PQ),加速相似性搜索。理解这些原理有助于利用矢量数据库处理大规模高维数据,应用于推荐系统、图像搜索等领域。随着技术发展,矢量数据库将扮演更重要角色。
|
1天前
|
SQL 关系型数据库 MySQL
MySQL数据库的约束+进阶版新增与查询-2
MySQL数据库的约束+进阶版新增与查询
11 1
|
3天前
|
存储 关系型数据库 分布式数据库
数据库索引回表困难?揭秘PolarDB存储引擎优化技术
PolarDB分布式版存储引擎采用CSM方案均衡资源开销与可用性。
数据库索引回表困难?揭秘PolarDB存储引擎优化技术
|
4天前
|
SQL 数据库
SQL数据库基础语法-查询语句
SQL数据库基础语法-查询语句
|
4天前
|
存储 监控 Apache
查询提速11倍、资源节省70%,阿里云数据库内核版 Apache Doris 在网易日志和时序场景的实践
网易的灵犀办公和云信利用 Apache Doris 改进了大规模日志和时序数据处理,取代了 Elasticsearch 和 InfluxDB。Doris 实现了更低的服务器资源消耗和更高的查询性能,相比 Elasticsearch,查询速度提升至少 11 倍,存储资源节省达 70%。Doris 的列式存储、高压缩比和倒排索引等功能,优化了日志和时序数据的存储与分析,降低了存储成本并提高了查询效率。在灵犀办公和云信的实际应用中,Doris 显示出显著的性能优势,成功应对了数据增长带来的挑战。
查询提速11倍、资源节省70%,阿里云数据库内核版 Apache Doris 在网易日志和时序场景的实践
|
9天前
|
SQL 关系型数据库 MySQL
【MySQL-5】DDL的数据库操作:查询&创建&删除&使用(可cv代码+演示图)
【MySQL-5】DDL的数据库操作:查询&创建&删除&使用(可cv代码+演示图)
|
10天前
|
缓存 关系型数据库 MySQL
MySQL数据库性能优化实战
【4月更文挑战第30天】本文探讨了MySQL性能优化实战技巧,包括硬件与配置优化(如使用SSD、增加内存和调整配置参数)、索引优化(创建合适索引、使用复合索引及定期维护)、查询优化(避免全表扫描、减少JOIN和使用LIMIT)、分区与分片(表分区和数据库分片),以及使用缓存、定期清理数据库和监控诊断。通过这些方法,可以提升数据库性能和响应速度。
|
10天前
|
存储 SQL 缓存
构建高效的矢量数据库查询:查询语言与优化策略
【4月更文挑战第30天】本文探讨了构建高效矢量数据库查询的关键点,包括设计简洁、表达性强的查询语言,支持空间操作、函数及索引。查询优化策略涉及查询重写、索引优化、并行处理和缓存机制,以提升查询效率和准确性。这些方法对处理高维空间数据的应用至关重要,随着技术进步,矢量数据库查询系统将在更多领域得到应用。
|
10天前
|
SQL 缓存 监控
如何在数据库查询中使用参数化查询?
【4月更文挑战第30天】如何在数据库查询中使用参数化查询?
21 1
|
11天前
|
存储 SQL 关系型数据库
mysql查询数据库表大小怎么操作
mysql查询数据库表大小怎么操作