加入收藏 | 设为首页 | 会员中心 | 我要投稿 云计算网_泰州站长网 (http://www.0523zz.com/)- 视觉智能、AI应用、CDN、行业物联网、智能数字人!
当前位置: 首页 > 站长学院 > MySql教程 > 正文

查询性能的优化 - 查询慢的基础知识:优化数据访问

发布时间:2016-01-18 13:40:22 所属栏目:MySql教程 来源:网络整理
导读:一个查询执行的不是很理想,大部分原因都是由于数据量过大。很多查询都筛选了大量的数据并且并没有什么作用。其实大部分不好的语句都可以访问更少的数据。我们
一个查询执行的不是很理想,大部分原因都是由于数据量过大。很多查询都筛选了大量的数据并且并没有什么作用。其实大部分不好的语句都可以访问更少的数据。我们可以通过两个步骤来分析性能差的查询语句。

找出你的应用程序所获取的数据是否超出了你的需求。意思就是它访问了过多的数据,但是它也可能访问了过多的列。

找出MySQL服务器是否分析了过多的行。

从数据库获得的数据是否超出了你的需要?

一些查询语句获取了很多不需要的数据,之后再把它们扔掉。这就需要MySQL服务器做额外的工作,加重了网络的负担,并且消耗了应用服务器的内存和CPU资源。

下面都是一些常见的错误。

获取了不需要的行

一个最常见的错误就是MySQL要提供所需的数据,而不是计算并且返回所有的数据集。我们看到在熟悉其他数据库的人设计的应用程序中,这种错误常常发生。这些开发人员常常用SELECT获取很多行,之后再取前N行,并且关闭了数据集。他们可能考虑到MySQL会提供10行并且中止了查询的执行,但是MySQL真正所做的时候生成了完整的结果集。客户端库获取了所有的行并且抛弃了很多行。最好的方案是在查询后加上LIMIT条件。

在表的多连接查询中获取所有的列

如果你想获取所有出现在Academy Dinosaur影片中的演员,不要写如下的语句

mysql> SELECT * FROM sakila.actor
    -> INNER JOIN sakila.film_actor USING(actor_id)
    -> INNER JOIN sakila.film USING(film_id)
    -> WHERE sakila.film.title = 'Academy Dinosaur';

这个查询语句会返回这三个表的所有列。正确的语句如下:

mysql> SELECT sakila.actor.* FROM sakila.actor...;

获取所有的列

当你看到select *的时候一定要有所怀疑。你真的需要所有的列么?也许不是。获取所有的列可能会使一些优化失效,比如覆盖索引,同样的会增加I/O,内存,CPU的消耗。

一些DBA因为这个原因已经禁用了SELECT *,并且当修改了表的列也会降低了发生错误的几率。

当然,获取一些超出你需要的数据也并不总是不好的。在许多我们研究的案例中,人们告诉我们这种浪费资源的方法可以简化一些开发,它能让开发者在不同的地方使用相同的代码。这一点是可以考虑的,只要你能明白性能的消耗在哪就行了。如果你在程序中应用了一些缓存方案或者有一些其他好的想法,获取不需要的数据还是很有用的。获取和缓存所有的对象可能要比许多单独获取一部分数据要更好些。

MySQL是否检查了过多的数据?

一旦你确定了你的查询获取了所需的数据,你就可以查看查询是否检查了太多的数据。在MySQL中,最简单的消耗指标是:

执行时间

所检查的行数

返回的行数

没有一个指标可以完美的衡量查询的消耗。但是它们能反映出MySQL执行一个查询所访问的数据并且能大约的推算出查询运行的速度。这三个指标都记录在慢查询日志中,因此要想知道是否检查了过多的数据,查看慢查询日志是最好的方法。

执行时间

在第二章我们已经讨论过了,在MySQL5.0以及之前的版本中,慢查询日志有很多的限制。包括了缺乏更细颗粒度的日志。

幸运的是,有许多补丁可以使你记录和测量微秒级别的查询。它们都包含在了MySQL5.1服务器之中了,但是如果你用的是老版本的话,只能打补丁了。要小心的是,不要过度的看重执行时间。看这个指标的原因是它是一个目标的指标,但是在变化的条件下它并不是一直不变的。其他的因素-比如存储引擎的锁,高并发,并且还有硬件-都可能影响到执行的时间。这个指标非常有助于f发现那些对应用响应时间或者服务器取读取的影响的查询语句,但是它不能给出实际的执行时间。

(编辑:云计算网_泰州站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读