MySQL - WHERE优化篇

平常开发中,编写SQL语句都避免不了使用到 WHERE关键字作条件过滤,细心的朋友就会发现,WHERE的不一样表现形式会对数据库性能形成必定影响,本章主要针对 WHERE优化策略进行讨论....

<!-- more -->mysql

优化要素

  • 想要让SELECT .... WHERE ...变快,第一就是检查一下是否能够增长索引。在WHERE子句中建立索引,能够加快求值、过滤、和最终检索结果的速度。为避免浪费磁盘空间,能够经过建立联合索引来加速多个相关查询。
  • 尽可能减小全表扫描的查询,尤为对于大表更要杜绝全表扫描。
  • 减小函数使用(尤为是耗时的函数)。一个函数可能在结果集中每行都被调用一次或者在一个表里面每一行都被调用一次,这样作效率是很是低的。
  • 掌握不一样存储引擎的优化方案,合理的运用索引技术。
  • 优化InnoDB事务。(对于统计型的数据,开启只读事务)
  • 避免将查询转换成比较难以理解的方式,以避免MySQL没法进行优化
  • 熟练掌握EXPLAIN计划
  • 调整MySQL用于缓存数据的内存大小
  • 减小锁表的状况

内置优化

在作JAVA开发中,经过指令重拍会对代码作必定程度的优化,在数据库中MYSQL优化器也作了一系列相关优化工做,下面要介绍的就是数据库作的内置优化sql

方案一: 删除没必要要的括号
((a AND b) AND c OR (((a AND b) AND (c AND d))))
-> (a AND b AND c) OR (a AND b AND c AND d)
方案二: 常量折叠/常量叠算
(a<b AND b=c) AND a=5
-> b>5 AND b=c AND a=5
更多: 其余方案
  • 索引使用常量表达式时只计算一次,因此尽量使用产生const的查询方式(主键查询)
  • 对于MyISAM和MEMORY表来讲,在一个单独的表上,若是使用COUNT(*)可是没有WHERE子句的话,那么就会直接从表的信息里面检索数据。当在一个表中用NOT NULL表达式的时候也是这么作的。
  • 发现无效的常量表达式。MySQL会及时发现无效SELECT语句,而后不返回数据。
  • WHERE查询中发现未使用GROUP BY或者聚合函数(好比COUNT(),MIN()等),那么HAVING会与WHERE合并。
  • 多表查询中,MYSQL会对表进行评估从而构造出更简单的查询
  • 优先读取常量表数据库

    • 空表或者一个有一行的表。
    • WHERE子句在PRIMARY KEY或者UNIQUE INDEX上的表,其中索引和常量表达式做比较,并被定义为NOT NULL缓存

      SELECT * FROM t WHERE primary_key = 1;
      SELECT * FROM t1,t2
        WHERE t1.primary_key= 1  AND t2.primary_key = t1.id;
  • 关联查询时,MySQL会去尝试全部的可能性,从而发现最好的的组合方式。当ORDER BYGROUP BY子句的列都位于同一个表时,该表将会第一个被连接。
  • 若是ORDER BYGROUP BY 字段不一样,或是除join queue中的第一个表以外其它含有ORDER BYGROUP BY的表都会为其建立临时表
  • 若是使用了 SQL_SMALL_RESULT 选项,那么MySQL就会在内存中建立一个临时表。
  • MySQL每次查询时都会检查是否有可用索引,除非MySQL优化器认为全表扫描性能更快。早期版本中认为索引扫描行占30%的时候就会换成全表扫描,但进过改进后,如今将根据表的大小、行的数目、I/O块大小等综合评估
  • 在某些状况下,MySQL会直接跳过数据文件直接从索引中读取内容(好比: 索引列都是数字,那么这时候会直接解析索引树
  • 跳过不匹配HAVING条件的内容

示例

查询快慢除软硬件优化外,索引是必不可少,下面列举一些使用索引提供查询速度的示例。微信

高效查询
SELECT COUNT(*) FROM tbl_name;

SELECT MIN(key_part1),MAX(key_part1) FROM tbl_name;

SELECT MAX(key_part2) FROM tbl_name
  WHERE key_part1 = constant;

SELECT ... FROM tbl_name
  ORDER BY key_part1,key_part2,... LIMIT 10;

SELECT ... FROM tbl_name
  ORDER BY key_part1 DESC, key_part2 DESC, ... LIMIT 10;
索引树查询(索引列是数字的状况下)
SELECT key_part1,key_part2 FROM tbl_name WHERE key_part1 = val;

SELECT COUNT(*) FROM tbl_name
  WHERE key_part1 = val1 AND key_part2 = val2;

SELECT key_part2 FROM tbl_name GROUP BY key_part1;
索引排序(无需单独排序传递)
SELECT ... FROM tbl_name
  ORDER BY key_part1,key_part2,... ;

SELECT ... FROM tbl_name
  ORDER BY key_part1 DESC, key_part2 DESC, ... ;

总结

最好的优化方案,跟着新版本走推陈出新,新版中不只扩展更多功能,同时会增强优化力度。虽然MySQL优化器为咱们作了不少事情,但开发过程当中改主意还得注意。架构

说点什么

祝各位元旦快乐,吃嘛嘛香,2018里把全部吹的牛逼都给实现咯。函数

关注微信公众号:battcn 后台回复 mysql 便可得到 《打造扛得住的MySQL数据库架构》性能

  • 我的QQ:1837307557
  • battcn开源群(适合新手):391619659
相关文章
相关标签/搜索