mysql高性能6章总结(下) mysql查询优化
6.5查询优化器的局限性
mysql优化器是有局限性的,有时需要我们改写查询以提高效率。
6.5.1关联子查询
子查询是mysql一个很不效率的地方。
这一节首先我们需要了解一下相关子查询:内外部查询间有一个关联条件,类似于join中的等值条件
书中说尽量不要使用in来写相关子查询。推荐使用exists与join的方式来替代。
我感到比较迷惑
书中说mysql优化器会将用in非关联子查询解析为exists关联子查询。那么用exists优化in有什么意义呢?
我做的两个测试中exists与in的explain结果是一致的?
Exists与in的不同通过英文的简单理解就可以明白,exists是存在,返回一个bool值,只要
子查询查到有一个值成立就立马返回,能减少子查询的消耗。
关联子查询的效率是很低的,每一条外部查询的数据行都要让内部查询执行一次。而关联查询join则是一次性将n*m的结果全部罗列,还能通过where条件筛选,更容易优化。(自己的理解)
如何用好关联子查询
子查询并不一定是效率不好的,在合适的时候它也可以使用。具体情况应该explain以后再看结果。
6.5.2union的限制
一些情况union无法将where条件下推到内层,例如分语句的limit20。Union的分语句不可能有超过20条被留下,limit20应该是可以下推的,我们需要手动说明。
这里要注意从临时表去除数据顺序是不固定的。
6.5.3索引合并优化
5.0以后索引已经可以通过索引合并和交叉过滤的方式来定位目标行。
类型列中显示为index_merge
6.5.4等值传递
在关联中对于关联条件的筛选可以下推到各个子查询中。
6.5.5并行执行
Mysql无法利用多核特性并行查询。
6.5.6哈希关联
Mysql不支持哈希关联,不过可以通过自实现的哈希索引来实现哈希关联。
6.5.7松散索引扫描
Mysql不支持松散索引扫描。5.0后在某些条件下可以实现松散索引扫描
Extra列显示 using index for group-by
6.5.8最大值最小值优化
Mysql并不能使用索引的来获取极值,即使索引是有序的,他依然进行全表扫描。有时候我们可以用limit加上指定索引来手动指定返回摸个索引的第一行或者前几行。这个问题myisam解决的不错啊。
6.5.9在同一个表上查询和更新
Mysql不允许在同一张表中同时进行查询与更新。
可以注意奥上文中关联子查询是需要两条查询进行嵌套的,当这两条sql一条为更新,一条为查询是就会报错。这时可以采用关联子查询一节中的处理方式将其转换为join查询的。
6.6查询优化器提示(hint)
这一节给出了dba控制sql的执行计划的方式,即hint。这里我不在罗列hint。在使用hint时要通过详细的测试hint是否能带来效率的提升。(delayed, straight_join, use index ,force index, ignore index)
6.7优化特定类型的查询
6.7.1优化count()
Mysql的count()是不统计空值的。只有才确定一行一定不为空的情况下才能统计行数。
Myisam的count()并不总是非常高效的只有没有where时myisam才能将存储的count(col)
值优化为count(*)才能高效的实现count(*)
简单的count优化
在myisam中我们知晓count(col)的代价很小,但我们需要一个count where 的数据时,可以在合适情况下采用总数减去不需要的行数的办法获取count。
使用近似值
这一类的代表为innodb这样的引擎,即通过explain执行计划来估算查询的行数。
跟复杂的优化
可以使用汇总表来记录时常要用到的统计值来优化。
6.7.2优化关联查询
- 关联字段有索引很重要的,但是只有内部查询需要索引,因为外部查询是用不到该列的索引的。
- 确保任何的group by与order by只涉及一个表中的列,这样mysql才能使用索引来优化这个过程。
- Mysql版本的升级可能会影响关联查询的执行方式
6.7.3优化子查询
尽量使用关联查询(醉了前面说那么多子查询还行后面还是让你用关联查询)
6.7.4优化group by和order by
Group by默认会按照分组字段进行排序,如果不需要排序,可以使用 order by NULL 来禁止排序。需要特定顺序也可以使用desc,asc。
Group by 语句中不于分组字段直接关联的都是无意义的返回值,不同的环境,可能有不同的非关联返回值。
Group by with rollup
超级聚合,可以将分组的结果进行一次超级聚合,即聚合后的总计。在分组项有多项式会有更多的组合。不过Group by with rollup 并不是处理此类需求的一个号的解决方式,最好还是通过程序来解决。
6.7.5优化limit分页
Limit能够减少返回的结果集,所以尽可能早的使用order by与limit能有效减少io次数。
对于offset(取数据的起始值)关键字,我们应该尽量不使用,可以用自定义书签的方式,来访问偏后的数据,但是这样往往需要数据字段中有一个可以预估增长方式的值。
6.7.6优化sql_calc_found_rows
这个hint要求sql扫描所有满足where条件的行,再根据limit抛弃不需要的行。这样的需求往往是我们需要提供一个总的记录数才需要给出该hint,
6.7.7优化union查询
一句话用union all而不用union。
使用union会给要求加入结果集的数据唯一,而对所有数据行进行唯一性检查,这样额外的开销。 当然跟好的做法是不使用union而将各个查询的结果返回给客户端,让客户端来实现union(union的结果集会保存在一个临时表中,返回给客户端有需要将临时表中的数据读取出来)。
6.7.8静态查询分析
通过工具为所有的查询语句做一个体检。
6.7.9使用用户自定义变量
使用用户自定义变量可以保存一些查询结果,用来在sql中实现应用程序中的逻辑而不是通过关联查询等等方式来体现逻辑。是一种解决方式,不过在存储过程中使用的比较多。
- 优化排名语句
自定义变量可以作为左值(可以赋值)。
可以通过自定义变量来自实现类似count的功能,甚至可以对’count’的过程加上条件!来实现排名功能!(具体事例书中查看)
- 避免重复查询刚刚插入的数据
标题很迷惑人,其实就是但你需要将你刚刚插入的数据返回时!Mysql没有相应的语法来一次性实现这样的功能(postgreSQL提供update return语法)。我们必须使用一条insert以及一条select两条语句来实现。
而使用变量保存我们刚刚跟新的值的就可以免于select语句的执行。
- 统计更新与插入数量
在Insert on duplicate key update 可以计算update的记录数,通过mysql返回的总行数可以知道insert的记录数。(Insert on duplicate key updatec1=values(c1)+0*(@x:=@x+1))
- 确认取值的顺序
但语句使用到using temporary与using filesort时可能会导致变量的值。可以通过一个字符处理函数将变量赋值包括进去。例如least()。
- 编写偷懒的union
可以通过一个变量的使用来避免第一个union分支已经找到数据的情况下,后续分支依然要执行的情况。
- 用户自定义变量的其他用处
总结:起来就是查询进行中的自定义单条数据判断条件控制。
6.8案例学习
6.8.1使用mysql构建一个对列表
- 应该尽量避免select for update,而应该使用在sql中connection_id()来判断有没有用户正在访问这条记录。
- 如果逻辑允许一个事务中应该先update再select会更好。
6.8.2计算两点间的距离
这个例子告诉我们。
- 少做事,用尽量少的逻辑来实现功能。(指的是少用sql实现)
- 能否使用索引会严重影响查询的效率,不过也不是无脑索引
- 尽可能的让应用程序来完成计算的部分。
体会:
第六章的内容其实就是介绍了sql的优化,以及我们在配合程序编写sql时应该注意什么?
在几个月的工作中,发现sql部分优化往往都不是前期开发的关键,因为,应用程序的处理会让我们比较轻易的将一整条sql拆分成多条简单的sql,在配合合适的索引,sql往往都不会有太大的问题。。但是也许程序发布以后流量打起来sql的问题就来了
mysql高性能6章总结(下) mysql查询优化的更多相关文章
- Mysql优化系列--Innodb引擎下mysql自身配置优化-转
原文链接:http://www.cnblogs.com/kevingrace/p/6133818.html 谢谢楼主 1.简单介绍 InnoDB给MySQL提供了具有提交,回滚和崩溃恢复能力的事务安全 ...
- MySQL高性能优化系列-目录
MySQL高性能优化系列-目录 (1)Mysql高性能优化规范建议 (2)电商数据库表设计 (3)MySQL分区表使用方法 (4)MySQL执行计划分析 (5)电商场景下的常见业务SQL处理 (6)M ...
- linux下mysql的卸载、安装全过程
卸载mysql 1.查找以前是否装有mysql 命令:rpm -qa|grep -i mysql 可以看到mysql的两个包: mysql-4.1.12-3.RHEL4.1 mysqlclient10 ...
- [转]Ubuntu10下MySQL搭建Amoeba系列(文章索引)
一.前言(Introduction) 使用了Amoeba有一段时间了,发现官方博客:Amoeba使用指南有很多地方都是错误的,在我实战中给到一些错误的指示,所以我想写些在搭建的实战中给大家一点指引.欢 ...
- Windows环境下Mysql如何快速导入或恢复表为innodb的数据
注: 一.这个是对Innodb的数据恢复.MyISAM不需要这么麻烦,只要数据文件存在直接复制过去就可以. 二.该方法只适用于 1:想要恢复或者导入表的ibd文件和frm文件 2:你不仅需有ibd和f ...
- (转)Windows下MySQL :GUI安装和使用(MySQL GUI tools)
原文:http://blog.csdn.net/dahunbi/article/details/52970815 MySQL GUI Tools是MySQL官方提供的图形化管理工具,功能很强大,值得推 ...
- Linux下MySQL/MariaDB Galera集群搭建过程【转】
MariaDB介绍 MariaDB是开源社区维护的一个MySQL分支,由MySQL的创始人Michael Widenius主导开发,采用GPL授权许可证. MariaDB的目的是完全兼容MySQL,包 ...
- 数据库:ubantu下MySQL安装指南
http://wiki.ubuntu.org.cn/MySQL%E5%AE%89%E8%A3%85%E6%8C%87%E5%8D%97 安装MySQL sudo apt-get install mys ...
- windowns环境下mysql 安装教程
windowns环境下mysql 安装教程 一:这里以绿色版安装为例(解压就可以使用) 下载地址: 下载页面:https://dev.mysql.com/downloads/mysql/ 2:点击 ...
随机推荐
- Winform关于未找到元数据文件.exe和不包含适合于入口点的静态“Main”方法
在三层架构中ItcastCaterModel项目是被其他项目引用的,所以输出类型为类库.
- 【Jenkins】testng+testNgXslt+ant优化测试报告
步骤: 准备: testng-results.xsl saxon-8.7.jar 下载地址:http://download.csdn.net/download/a804229570/10210509 ...
- 为Linux技术学习推荐看的书籍—《Linux就该这么学》
成长,是一种经历:经历,是一种人生的体验.人生的意义不在于我们拥有了什么,而在于从中我们体悟了什么.在这短短的三年,却在我的人生中弥足珍贵,在脑海中记忆犹新,在这大学三年里,我从一个莽撞少年成长为一名 ...
- Python *Mix_w8
文件操作的函数 文件可迭代 open(文件名(路径), mode="?", encoding="字符集") f = open("../Python/是 ...
- leetcode 翻转二叉树
翻转二叉树的步骤: 1.翻转根节点的左子树(递归调用当前函数) 2.翻转根节点的右子树(递归调用当前函数) 3.交换根节点的左子节点与右子节点 class Solution{ public: void ...
- [Codeforces778E]Selling Numbers
Problem 给一个由问号和数字组成的数字串A(问号表示任一数字). 再给定n个数字Bi,和0~9的数字的价值. F(x)表示x各个位数上的价值和.问A为何值时,sum(F(Bi+A))的值最大为多 ...
- 【阅读笔记】《C程序员 从校园到职场》第六章 常用文件操作函数 (Part 1)
参考链接:https://blog.csdn.net/zhouzhaoxiong1227/article/details/24926023 让你提前认识软件开发(18):C语言中常用的文件操作函数总结 ...
- Linux 云服务器中安装 rinetd 进行转发端口实现
端口转发映射的程序叫rinetd,直接make编译安装即可. wget http://www.boutell.com/rinetd/http/rinetd.tar.gz&&tar -x ...
- WebView性能、体验分析与优化
育新 徐宏 嘉洁 ·2017-06-09 20:03 在App开发中,内嵌WebView始终占有着一席之地.它能以较低的成本实现Android.iOS和Web的复用,也可以冠冕堂皇的突破苹果对热更新的 ...
- ubuntu 网络配置
检查网络配置命令:ifconfig 一.通过配置文件配置 新手没怎么用过Ubuntu,所以走了不少弯路,网上找了很多方法,大都没对我起到帮助作用,所以把自己的配置方法写一写. Ubuntu上连了两块网 ...