资讯专栏INFORMATION COLUMN

MySQL - WHERE优化篇

chengjianhua / 992人阅读

摘要:为避免浪费磁盘空间,可以通过创建联合索引来加速多个相关查询。发现无效的常量表达式。高效查询索引树查询索引列是数字的情况下索引排序无需多带带排序传递总结最好的优化方案,跟着新版本走推陈出新,新版中不仅扩展更多功能,同时会加强优化力度。

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

优化要素

想要让SELECT .... WHERE ...变快,第一就是检查一下是否可以增加索引。在WHERE子句中创建索引,可以加快求值、过滤、和最终检索结果的速度。为避免浪费磁盘空间,可以通过创建联合索引来加速多个相关查询。

尽量减少全表扫描的查询,尤其对于大表更要杜绝全表扫描。

减少函数使用(尤其是耗时的函数)。一个函数可能在结果集中每行都被调用一次或者在一个表里面每一行都被调用一次,这样做效率是非常低的。

掌握不同存储引擎的优化方案,合理的运用索引技术。

优化InnoDB事务。(对于统计型的数据,开启只读事务)

避免将查询转换成比较难以理解的方式,以免MySQL无法进行优化

熟练掌握EXPLAIN计划

调整MySQL用于缓存数据的内存大小

减少锁表的情况

内置优化

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

方案一: 删除不必要的括号
   ((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>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

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/47455.html

相关文章

  • MySQL - RANGE优化

    摘要:优化器在常量传播阶段,会将一些非常量值转换为常量。定义对于索引和索引来说,索引的范围优化基本上只适用于等值查询。会执行额外的检查来筛选满足范围条件但不满足子句的行。虽然优化器为我们做了很多事情,但开发过程中该主意还得注意。 Range Access使用单个索引的方式来检索包含在一个或多个索引值区间内的表行的子集。它也适用于单列或复合(组合)索引... 单列索引 对于单列索引,索引值...

    LittleLiByte 评论0 收藏0
  • MySQL性能管理及架构设计(三):SQL查询优化、分库分表 - 完结

    摘要:第二阶段依照执行计划和存储引擎进行交互这个阶段包括了多个子过程一条查询可以有多种查询方式,查询优化器会对每一种查询方式的存储引擎统计信息进行比较,找到成本最低的查询方式,这也就是索引不能太多的原因。 上一篇:MySQL性能管理及架构设计(二):数据库结构优化、高可用架构设计、数据库索引优化 一、SQL查询优化(重要) 1.1 获取有性能问题SQL的三种方式 通过用户反馈获取存在性能问...

    kycool 评论0 收藏0
  • mysql - 收藏集 - 掘金

    摘要:步优化以及其它数据库后端掘金原文链接在发表了一篇简洁有效有趣和令人信服的分钟教程描述了如何进行优化。关于的七种后端掘金对于的,在学习起来可能是比较乱的。 5 步优化 MongoDB 以及其它数据库 - 后端 - 掘金原文链接 Jared Rosoff 在 Scale Out Camp 发表了一篇简洁、有效、有趣和令人信服的《8 分钟 MongoDB 教程》描述了如何进行 MongoDB...

    roadtogeek 评论0 收藏0
  • mysql - 收藏集 - 掘金

    摘要:步优化以及其它数据库后端掘金原文链接在发表了一篇简洁有效有趣和令人信服的分钟教程描述了如何进行优化。关于的七种后端掘金对于的,在学习起来可能是比较乱的。 5 步优化 MongoDB 以及其它数据库 - 后端 - 掘金原文链接 Jared Rosoff 在 Scale Out Camp 发表了一篇简洁、有效、有趣和令人信服的《8 分钟 MongoDB 教程》描述了如何进行 MongoDB...

    Donald 评论0 收藏0
  • MySQL™ 参考手册(优化SQL语句)

    优化SQL语句 数据库应用程序的核心逻辑是通过SQL语句执行的,无论是直接通过解释器发出,还是通过API在后台提交。本节中的调优指南有助于加快各种MySQL应用程序的速度,这些指导原则包括读取和写入数据的SQL操作、通常SQL操作的幕后开销以及在特定场景(如数据库监视)中使用的操作。 优化SELECT语句 以SELECT语句的形式的查询执行数据库中的所有查找操作,优化这些语句是首要任务,无论是为动...

    adie 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<