`

提高MySQL索引策略一:隔离查询列

    博客分类:
  • db
 
阅读更多

在mysql中执行查询时,如果没有将查询条件(条件列)隔离出来,那么查询引擎则无法利用建立在该列上的索引进行数据获取.这里的"隔离"意味着查询条件字段不能作为表达式的一部分出现,所以,如果在查询语句中指定表达式条件,就必须单独将条件列置于表达式的一边.举个简单例子,

 

SELECT actor_id FROM sakila.actor WHERE actor_id + 1 = 5;

 ,mysql无法对上述的actor_id进行索引查询,尽管从人们能一眼看出actor_id为4,但是mysql不会对该表达式进行计算.这种计算完全靠你来完成的,你应该养成简化查询语句的习惯(很多很多),对于这条sql,actor_id应该单独位于等号的一边.

 

这里有个很常见的例子:

SELECT ... WHERE TO_DAYS(CURRENT_DATE) - TO_DAYS(date_col) <= 10;

 这里的sql将数据库中date_col到当前时间10天之内的数据检索出来,date_col上的索引在这个情况下完全是不可用的,因为TO_DAYS()函数式无法利用索引的,可以将检索条件更改为如下:

SELECT ... WHERE date_col >= DATE_SUB(CURRENT_DATE, INTERVAL 10 DAY);

 date_col完全可以利用索引来提高查询效率.除了这些,还能做的就是将CURRENT_DATE替换为当前时间,我相信上层调用都能获取到当前时间(如果你不要求服务器时间和mysql时间一致),还有一个提交CURRENT_DATE的原因是mysql无法对该条sql进行缓存,毕竟不同日期sql的执行时间都是不一致的.

 

上面是high-performance-mysql中的章节翻译,下面就进行一些简单的测试(数据50w+,innodb,timestamp索引,字段唯一度0.35),首先是不对查询列进行隔离.

1.通过条件控制获取所有数据(588951):

select sql_no_cache count(...) where to_days(current_date) - to_days(update_time) < 100;
 执行时间:1s

 

2.获取一半数据(276009):

select sql_no_cache count(...) where to_days(current_date) - to_days(update_time) < 60;
 执行时间:0.99s

 

3.获取极少部分数据(20161);

 

select sql_no_cache count(...) where to_days(current_date) - to_days(update_time) < 41;
 执行时间:0.97s

 

 

下面是对update_time进行列隔离.

1.通过条件控制获取所有数据(588951):

select sql_no_cache count(...) where update_time > date_sub(current_date ,interval 100 day);
 执行时间:1.18s

 

2.获取一半数据量(288821):

select sql_no_cache count(...) where update_time > date_sub(current_date ,interval 60 day);

 执行时间:0.58s

3.获取极少数据(35220):

select sql_no_cache count(...) where update_time > date_sub(current_date ,interval 41 day);

 执行时间:0.07s

最后把索引去除,进行数据的获取(不管是数据的多寡),未进行隔离的查询为1.00s,而进行隔离的查询为1.10s,所以

可以看出,在有索引的字段上进行条件查询,最好将该字段至于表达式的一边,否则索引对于查询的高效将无法得到发挥(以上的sql执行时间都通过100次计算的平均值得出)

 

分享到:
评论

相关推荐

    高性能MySQL(第3版).part2

    5.3高性能的索引策略153 5.3.1独立的列153 5.3.2前缀索引和索引选择性153 5.3.3多列索引157 5.3.4选择合适的索引列顺序159 5.3.5聚簇索引162 5.3.6覆盖索引171 5.3.7使用索引扫描来做排序175 5.3.8压缩...

    mysql面试题-mysql经典面试题目-数据库的基本概念-SQL语法-事务处理-索引优化-性能调优-mysql-面试题目

    为什么使用索引可以提高查询性能? 什么是事务?MySQL如何支持事务处理? 什么是主键和外键?它们之间有什么区别? 什么是数据库范式?列举一些常见的数据库范式。 什么是数据库连接池?为什么使用连接池可以...

    10道精选MySQL面试题

    当表数据量很大时,如何进行SQL查询优化以提高查询效率? 如何设计合适的索引来改善特定查询语句的性能? InnoDB存储引擎中行锁的类型有哪些?在什么场景下会使用共享锁和排他锁? 什么是死锁?MySQL如何检测和处理...

    mysql面试题文档,主要讲述了一些数据库的基本理论

    索引和查询优化:理解索引的作用和原理,掌握查询优化的方法和技巧,能够根据查询需求选择合适的索引类型和优化策略。 存储过程和触发器:了解存储过程和触发器的概念和作用,掌握存储过程的编写和触发器的应用场景...

    100道mysql的面试题

    2. 文档内容包括mysql索引,索引失效,覆盖索引,回表,二叉树,死锁,读写分离,分库分表,分库分表中间件,聚集索引或非聚集索引, 索引优化,事务级别,幻读,脏读,不可重复读,数据库的乐观锁和悲观锁,SQL优化...

    PHP和MySQL Web开发第4版pdf以及源码

    12.2 提高MySQL数据库的安全性 12.2.1 从操作系统角度来保护MySQL 12.2.2 密码 12.2.3 用户权限 12.2.4 Web问题 12.3 获取更多关于数据库的信息 12.3.1 使用SHOW获取信息 12.3.2 使用DESCRIBE获取关于列的...

    PHP和MySQL WEB开发(第4版)

    12.2 提高MySQL数据库的安全性 12.2.1 从操作系统角度来保护MySQL 12.2.2 密码 12.2.3 用户权限 12.2.4 Web问题 12.3 获取更多关于数据库的信息 12.3.1 使用SHOW获取信息 12.3.2 使用DESCRIBE获取关于列的信息 ...

    面试宝典MySql.txt

    MyISAM 是 MySQL 官方提供默认的存储引擎,其特点是不支持事务、表锁和全文索引,对于一些 OLAP(联机 分析处理)系统,操作速度快。 每个 MyISAM 在磁盘上存储成三个文件。文件名都和表名相同,扩展名分别是.frm...

    PHP和MySQL Web开发第4版

    12.2 提高MySQL数据库的安全性 12.2.1 从操作系统角度来保护MySQL 12.2.2 密码 12.2.3 用户权限 12.2.4 Web问题 12.3 获取更多关于数据库的信息 12.3.1 使用SHOW获取信息 12.3.2 使用DESCRIBE获取关于列的...

    Mysql innodb 存储引擎全揭秘

    同时使用一种 -- next-key locking 的锁策略来避免幻读现象的产生,还提供了插入缓冲(insert buffer) 二次写(double write) 自适应哈希索引,预读(read ahead)等高性能和高可用的功能。对于表中的数据innodb...

    江神JAVA开发面经超级总结

    MySQL的索引是一种数据结构,用于快速定位数据。MySQL的索引有两种:B树索引和哈希索引。B树索引用于范围查询,哈希索引用于等值查询。 二十三、InnoDB的事务和日志的实现方式 InnoDB的事务和日志的实现方式是基于...

    基于mysql体系结构的深入解析

    mysql各个存储引擎概述:innodb存储引擎:[/color][/b] 面向oltp(online transaction processing)、行锁、支持外键、非锁定读、默认采用repeaable级别(可重复读)通过next-keylocking策略避免幻读、插入缓冲、二次...

    MySQL存储引擎InnoDB的配置与使用的讲解

    MyISAM和InnoDB是MySQL最常有的存储引擎,上一篇我们讲述了InnoDB与MyISAM之间的区别;由于MyISAM不支持事务,当我们需要使用一个健壮的事务型存储引擎的时候,InnoDB必然是最好的选择。 innodb 通过多版本并发控制...

    python web开发工程师面试的题目与技巧.doc

    通过对这些知识点的掌握,可以帮助开发工程师更好地准备面试,并提高面试的通过率。 Python基础知识 * 闭包相关:手写闭包,使用闭包实现单例,闭包的使用场景 * 对生成器与迭代器的认识 * 高阶函数:sorted * 元...

    03开源NewSql数据库TiDB-Deep Dive into TiDB

    在这一版本中,SQL 执行引擎引入新的内部数据表示方式 --- `Chunk`,一个结构中保存一批数据而不仅是一行数据,同一列的数据在内存中连续存放,使得内存使用更紧凑,这样带来了几点好处:1. 显著减小了内存消耗; 2....

    asp.net知识库

    NET委托:一个C#睡前故事 [推荐] - [原创] Microsoft .NET策略及框架概述 卸载Class? Web Form 窗体 如何实现web页面的提示保存功能 在ASP.Net中两种利用CSS实现多界面的方法 如何在客户端调用服务端代码 页面一...

    互联网金融Hbase大数据实践.pptx

    水平扩展传统 DB 需要定期将线上数据迁移至历史 DB,需要建立复杂的迁移策略,易出错。 HBase 挑战和应对 HBase 作为大数据实践中的重要组件,面临着多种挑战,如业务局限、二级索引和集群复制等。为了解决这些...

    Java常见面试题208道.docx

    165.一张自增表里面总共有 7 条数据,删除了最后 2 条数据,重启 mysql 数据库,又插入了一条数据,此时 id 是几? 166.如何获取当前数据库版本? 167.说一下 ACID 是什么? 168.char 和 varchar 的区别是什么? 169...

    【白雪红叶】JAVA学习技术栈梳理思维导图.xmind

    接口隔离原则 迪米特原则 设计模式 结构模式 适配器模式 桥接模式 组合模式 装饰模式 外观模式 享元模式 代理模式 创建模式 抽象工厂模式 工厂方法模式 建造这模式 原型模式 单例模式 行为模式 ...

Global site tag (gtag.js) - Google Analytics