`
情情说
  • 浏览: 38868 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

理解索引:索引优化

 
阅读更多

 

最近有个需求,要修改现有存储结构,涉及查询条件和查询效率的考量,看了几篇索引和HBase相关的文章,回忆了相关知识,结合项目需求,说说自己的理解和总结。

错过的朋友可以先回顾下前3篇文章:

  1. 索引结构和数据定位过程
  2. 查询过程和高级查询
  3. 执行计划详细介绍

上一篇详细介绍了explain命令,通过该命令,可以定位出在哪一步出现了性能问题,下一步就是通过优化索引来解决它。

部分内容摘录了几个博友的文章,最后会给出文章链接,感谢他们的精彩分析。

常见优化方法

联合索引最左前缀原则

复合索引遵守「最左前缀」原则,查询条件中,使用了复合索引前面的字段,索引才会被使用,如果不是按照索引的最左列开始查找,则无法使用索引。

比如在(a,b,c)三个字段上建立联合索引,那么它能够加快a|(a,b)|(a,b,c)三组查询的速度,而不能加快b|(b,a)这种查询顺序。

另外,建联合索引的时候,区分度最高的字段在最左边。

不要在列上使用函数和进行运算

不要在列上使用函数,这将导致索引失效而进行全表扫描。

例如下面的 SQL 语句:

select * from artile where YEAR(create_time) <= '2018';

即使 date 上建立了索引,也会全表扫描,可以把计算放到业务层,这样做不仅可以节省数据库的 CPU,还可以起到查询缓存优化效果。

负向条件查询不能使用索引

负向条件有:!=、<>、not in、not exists、not like 等。

select * from artile where status != 1 and status != 2;

可以使用in进行优化:

select * from artile where status in (0,3)
使用覆盖索引

所谓覆盖索引,是指被查询的列,数据能从索引中取得,而不用通过行定位符再到数据表上获取,能够极大的提高性能。

可以定义一个让索引包含的额外的列,即使这个列对于索引而言是无用的。

避免强制类型转换

当查询条件左右两侧类型不匹配的时候会发生强制转换,强制转换可能导致索引失效而进行全表扫描。

如果phone字段是varchar类型,则下面的SQL不能命中索引:

select * from user where phone=12345678901;

可以优化为:

select * from user where phone='12345678901';
范围列可以用到索引

范围条件有:<、<=、>、>=、between等。

范围列可以用到索引,但是范围列后面的列无法用到索引,索引最多用于一个范围列,如果查询条件中有两个范围列则无法全用到索引。

更新频繁、数据区分度不高的字段上不宜建立索引

更新会变更B+树,更新频繁的字段建立索引会大大降低数据库性能。

「性别」这种区分度不大的属性,建立索引没有意义,不能有效过滤数据,性能与全表扫描类似。

区分度可以使用 count(distinct(列名))/count(*) 来计算,在80%以上的时候就可以建立索引。

索引列不允许为null

单列索引不存null值,复合索引不存全为null的值,如果列允许为 null,可能会得到不符合预期的结果集。

避免使用or来连接条件

应该尽量避免在 where 子句中使用 or 来连接条件,因为这会导致索引失效而进行全表扫描,虽然新版的MySQL能够命中索引,但查询优化耗费的 CPU比in多。

模糊查询

前导模糊查询不能使用索引,非前导查询可以。

优化案例

利用延迟关联或者子查询优化超多分页场景

MySQL 并不是跳过 offset 行,而是取 offset+N 行,然后返回放弃前 offset 行,返回 N 行。

当 offset 特别大的时候,效率非常低下,要么控制返回的总页数,要么对超过特定阈值的页数进行SQL改写。

可以先快速定位需要获取的id段,然后再关联:

selecta.* from 表1 a,(select id from1 where 条件 limit 1000000 ,10 ) b where a.id=b.id
如果明确知道只有一条结果返回,limit 1 能够提高效率

虽然自己知道只有一条结果,但数据库并不知道,明确告诉它,让它主动停止游标移动。

如何建立索引
where a=1 and b=1  
where b=1  
where b=1 order by time desc

建议建立两个索引,即 idx_ab(a,b) 和 idx_b_time(b,time)

MySQL 的查询优化器会自动调整where子句的条件顺序以使用适合的索引,对于上面的第一条 SQL,如果建立索引为idx_ba(b,a) 也是可以用到索引的。

多值匹配和范围匹配

假如有联合索引(empno、title、fromdate),下面的 SQL 是否可以用到索引,如果可以的话,会使用几个?

select * from employee.titles  
where emp_no between '10001' and'10010'  
and title='软件工程师'   
and from_date between '2008-01-01'and '2018-01-01'

可以使用索引,可以用到索引全部三个列,这个 SQL看起来是用了两个范围查询,但作用于empno上的between实际上相当于in,也就是说empno 实际是多值精确匹配。

在 MySQL 中要谨慎地区分多值匹配和范围匹配,否则会对 MySQL 的行为产生困惑。

联合索引的最左匹配原则

假如建立联合索引(a,b,c),下列语句是否可以使用索引,如果可以,使用了那几列?

where a= 3  // 是,使用了a列
where a= 3 and b = 5  // 是,使用了ab列  
where a = 3 and c = 4 and b = 5  // 是,使用了 a,b,c 列  
where b= 3 // 否
where a= 3 and c = 4  // 是,使用了a列  
where a = 3 and b > 10 and c = 7  // 是,使用了 a,b 列  
where a = 3 and b like 'xx%' andc = 7  // 是,使用了 a,b 列
根据区分度创建索引

有如下查询语句,查找指定产品已审核(status=1)的评论:

SELECT user_id,title,content FROM `comment`
WHERE status=1 AND product_id=1
LIMIT 0,5 ;

可以建立联合索引,status和product_id,但是哪个放左边就要计算区分度:

SELECT COUNT(DISTINCT status)/COUNT(*) AS audit_rate,
COUNT(DISTINCT product_id)/COUNT(*) AS product_rate
FROM comment;

一般product的区分度会高点,可以创建如下索引:

CREATE INDEX idx_productID_Status ON comment(product_id,status)
排序字段索引

查看某个用户最近20条登录记录,按时间排序:

select *  from login_history where uid = $uid order by create_time desc limit 20;

建立uid+timeline复合索引,将排序引入到索引结构中,数据库负载骤降。

参考文章:

  1. MySQL 索引及优化实战
  2. 索引使用的注意事项

欢迎扫描下方二维码,关注我的个人微信公众号,查看更多文章 ~

 


情情说

 

 

1
0
分享到:
评论
1 楼 情情说 2018-06-11  
喜欢的可以关注公众号:情情说

相关推荐

    尚硅谷mysql高级:索引、优化

    2. 索引优化:合理设计索引,根据查询模式创建最合适的索引。避免索引过多,因为这会增加写操作的开销。 3. 数据库设计:遵循第三范式,减少数据冗余,提高数据一致性。考虑数据分布,合理分区和分表。 4. 存储...

    数据库索引设计和优化

    三、索引优化 1. 选择性:索引的选择性越高,表示索引区分度越大,查询性能通常越好。选择性低的列不适合建立索引。 2. 索引维护:索引需要随着数据的增删改进行维护,因此要考虑操作频率和复杂度。 3. 分区索引:...

    mssql索引优化工具

    **SQL Server索引优化工具详解** SQL Server(简称MSSQL)是一款广泛应用的企业级关系型数据库管理系统,其性能优化是数据库管理员(DBA)的重要工作之一。索引作为提升查询性能的关键工具,对于大型数据库来说尤其...

    SQL语句索引优化_sql索引降龙十八掌(Oracle)

    在数据库管理领域,SQL语句的索引优化是提高数据查询效率的关键技术,尤其是在大型企业级应用中。本文将深入探讨Oracle数据库中的索引优化原则和方法,这些原则和方法同样适用于其他数据库系统。让我们一起领略"SQL...

    书籍:Oracle与MySQL数据库索引设计与优化

    三、索引优化策略 1. 索引选择性:索引的选择性越高,索引的区分度越大,查询性能越好。应为区分度高的列创建索引。 2. 索引覆盖:如果查询只涉及到索引中的列,MySQL和Oracle都可能避免全表扫描,提高性能。 3. ...

    SQL Server 2000完结篇系列之七:SQL Server 2000索引优化详解

    本文将深入探讨SQL Server 2000中的索引优化,旨在帮助数据库管理员和开发人员理解如何有效地利用索引来提升系统性能。 一、索引的基本概念 索引是一种特殊的数据结构,它允许数据库快速定位到表中的特定行,类似于...

    SQL 索引优化

    在数据库管理中,SQL索引优化是提升查询性能的关键技术之一。索引如同书籍的目录,可以帮助数据库系统快速定位...理解索引的工作原理和优缺点,能够帮助我们更好地管理和维护数据库,为应用程序提供更快更稳定的服务。

    深入解析MongoDB聚合与索引:提升数据库效能的关键策略

    总结来说,理解并熟练运用MongoDB的聚合操作和索引机制对于优化数据库性能至关重要。通过合理的聚合管道设计和索引策略,可以极大地提高数据处理和查询的效率,从而提升整体应用的性能。对于开发者而言,掌握这些...

    SQLServer 索引查询优化指南

    - 使用连接优化:优化JOIN操作,如避免大表连接小表,考虑使用临时表或子查询优化。 6. **索引维护** - 定期重建索引以优化碎片,保持索引的效率。 - 监控统计信息:更新表的统计信息有助于查询优化器做出更准确...

    数据库索引 设计和优化

    数据库索引设计与优化是数据库管理系统中的核心环节,它直接影响着数据查询的速度和系统的整体性能。...只有充分理解索引的工作原理和特性,才能在实际应用中发挥出它的最大价值,提升数据库系统的整体性能。

    SQL优化-索引word19页

    理解索引的工作原理,合理选择索引类型,以及遵循最佳实践,都能帮助我们构建一个高效、响应迅速的数据库系统。在实际工作中,应结合业务需求和性能监控,持续优化索引策略,以实现最优的数据库性能。

    DB2索引及其优化(设计,优化,问题分析,解答,举例)

    DB2索引及其优化 DB2索引设计及其优化是...在本文中,我们讨论了DB2索引的概念、创建索引、建立索引注意事项、索引分类和索引优化等方面的知识点,并提供了一些有用的提示和建议,以帮助读者更好地理解和应用DB2索引。

    09 oracle的索引 PPT

    总结,Oracle的索引是提升数据库性能的关键工具,理解索引的工作原理,合理设计和管理索引,能有效优化数据库的查询性能,但同时也要注意其带来的额外存储和维护成本。在实际应用中,需要根据业务需求和查询模式,...

    数据库索引设计与优化,数据库必学经典

    四、索引优化策略 1. 使用覆盖索引:如果查询只需要索引中的信息,覆盖索引可以让数据库避免回表,提高性能。 2. 避免索引失效:避免在索引列上使用非等值比较操作(如LIKE、BETWEEN)或函数,这可能导致索引无法被...

    MYSQL索引知识

    MySQL索引知识是数据库管理中至...理解并正确使用MySQL索引对于数据库性能优化至关重要。在设计数据库时,应根据实际需求和数据特性合理创建索引,以平衡查询速度与维护成本。记住,索引不是越多越好,而是要恰到好处。

    mysql查询优化之索引优化

    MySQL查询优化是数据库管理中的关键环节,特别是在大数据量的场景下,索引优化能显著提升查询性能。本文将深入探讨“mysql查询优化之索引优化”这一主题。 首先,了解索引的基本概念至关重要。索引是数据库为了快速...

    数据库 索引及优化

    ### 数据库索引及优化详解 #### 一、数据库索引的重要性 数据库索引就像是图书中的目录,能够显著提升查询速度。例如,在执行查询 `SELECT * ...通过对索引的理解和正确应用,可以有效提升系统的响应速度和整体性能。

    基于索引的数据库查询优化

    在数据库管理领域,基于索引的查询优化是提高数据检索速度和...理解索引的工作原理,合理创建和维护索引,以及优化SQL语句,都是提高数据库性能的重要手段。开发人员和DBA应当持续关注这些方面,以确保系统的高效运行。

    Oracle数据库索引优化方法探析.pdf

    Oracle 数据库管理员需要深刻理解 Oracle 机制,采用更加灵活的方法,有效进行索引优化,提升查询效率。 在 Oracle 生产系统中,索引优化是一项重要的工作。 Oracle 数据库管理员需要根据实际情况,选择合适的索引...

    深入浅出理解索引结构

    ### 深入浅出理解索引结构 在数据库领域,索引是提高查询效率的重要手段之一。本文将深入探讨索引的基本概念及其在Microsoft SQL Server中的应用,并着重讲解聚集索引与非聚集索引的区别。 #### 索引的概念 索引...

Global site tag (gtag.js) - Google Analytics