高性能的MySQL(6)查询慢与重构查询

只有好的库表结构、合理的索引还不够,我们还需要合理的设计查询,齐头并进,一个不少才能充分发挥MySQL的优势。

一、查询为什么会慢?

每一个查询由一系列的子任务组成,每个子任务都会消耗一定的时间。这个我们在之前的单个查询分析时已经简单介绍了,当然还有额外的因素,比方说包括网络,CPU计算,统计信息,执行计划,锁等待等操作,或者底层引擎在调用内存,CPU操作,I/O操作等上的消耗时间。

优化查询的目的就是减少和消除这些操作所花费的时间。

查询性能低下的最基本原因是访问的数据太多,大部分的性能低下的查询可以通过减少访问的数据量进行优化,一般有2个简单的分析方法:

1、确认应用程序是否返回了大量超过需要的数据,这就是说访问了太多的行,也有时候是因为访问了太多的列,这会增加很多额外的开销,包括,网络,CPU,内存等。

一些常见的例子:

a、查询不需要的记录

一个常见的错误是常常会以为MySQL会只返回需要的数据,实际上却是先返回全部的查询结果再进行计算,一个简单有效的解决方法是在查询后面加上LIMIT。

b、多表关联时返回全部列

比如,要查找所有在电影hreo中出现的演员,不要这样去写

select * from actor
inner join film_actor using(actor_id)
inner join film using(film_id)
where film.title = "hreo";

这会返回三个表的全部列,应该只返回需要的列

select actor.* from actor
inner join film_actor using(actor_id)
inner join film using(film_id)
where film.title = "hreo";

c、不要总是取出全部的列

select * from actor....

d、重复查询相同的数据

例如在用户评论的地方需要查询用户的头像,如果用户多次评论,可能会反复查询这个数据,可以先缓存起来,这样会更好。

2、确认MySQL服务层是否在返回前检索大量超过需要的数据行。

如果查询为了返回结果扫描过多的数据,那么就不合适了,一般看3个指标:

a、响应时间

响应时间分为服务时间和排队时间。这个很难细分,如果是在一个合理的值,那就可以接受。

b、扫描的行和返回的行

这个在一定程度上能够说明该查询找到需要的数据效率怎么样。理想的情况下,扫描的行和返回的行是相同的,不过实际中这是很难的,特别是做关联查询时。

c、扫描的行和访问类型

在explain语句中的type列反应了访问类型。从全表扫描到索引扫描,范围扫描,唯一索引查询,常数引用等,速度从慢到快,扫描的行从大到小。一般我们增加一个合适的索引就可以很高效了。

CREATE TABLE `emp5` (
  `id` int(11) NOT NULL DEFAULT '0',
  `name` varchar(100) NOT NULL,
  `job` varchar(100) NOT NULL,
  `num1` int(10) DEFAULT NULL,
  `num2` int(10) DEFAULT NULL,
  `num3` int(10) DEFAULT NULL,
  `job_num` int(10) DEFAULT NULL,
  `d` date DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `job_num` (`job_num`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

查看本栏目更多精彩内容:http://www.bianceng.cnhttp://www.bianceng.cn/database/MySQL/

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索数据
, 查询
, null
, 时间
, default
, 一个
, 重构索引
, mysql局域网访问慢
, MySQL查看慢查询
查询返回null
高性能mysql、高性能mysql第四版、高性能mysql pdf、高性能mysql第4版、高性能mysql mobi,以便于您获取更多的相关知识。

时间: 2024-11-28 20:59:04

高性能的MySQL(6)查询慢与重构查询的相关文章

高性能的MySQL(6)查询执行机制(一)

希望优化查询性能的时候,最好的办法是弄清楚MySQL是如何优化和执行查询的.了解了内部机制,才能更好的实施设计. 当MySQL执行一个查询时,到底做了什么,先看一副图吧: 1.客户端发送一条查询给服务器. 2.服务器先检查查询缓存,如果命中了缓存,则立刻返回缓存中的结果,否则进入下一步. 3.服务器端进行SQL解析.预处理.再由优化器生成对应的执行计划. 4.MySQL根据优化器生成的执行执行计划,调用存储引擎的API来进行查询. 5.将结果返回给客户端 上面的每一步都很复杂,特别是查询优化器这

高性能的MySQL(2)慢查询

一.剖析MySQL查询 1.首先从慢查询开始,慢查询是开销最低,精度最高的测量查询时间的工具. a.开始mysql的慢查询,修改my.conf [mysqld] #开启慢查询 log_slow_queries = ON #指定日志文件存放位置,可以为空,系统会给一个缺省的文件host_name-slow.log log-slow-queries = /usr/local/mysq/var/slowquery.log #记录超过的时间,默认为10s long_query_time = 1 #log

【转载】低成本和高性能的MySQL云数据库的实现淘宝 MySQL

低成本和高性能的MySQL云数据库的实现 作者: 鸣嵩/曹伟(集团技术专家) 本文刊登于<程序员>杂志2012年12期上,转载请注明         UMP(Unified MySQL Platform)系统是淘宝核心系统数据库团队开发的低成本和高性能的MySQL云数据方案,关键模块采用Erlang语言实现.系统中包含了controller服务器.proxy服务器.agent服务器.API/Web服务器.日志分析服务器.信息统计服务器等组件,并且依赖于Mnesia.LVS.RabbitMQ.Z

高性能的MySQL(5)索引策略-索引案例分析

理解索引最好的办法是结合实例,接下来分析一个例子. 假设要设计一个在线约会网站,用户信息表有很多列,包括国家,地区,城市,性别,眼睛颜色等等.网站必须支持上面的各种组合来搜索用户,包括根据用户的最后在线时间,评分等进行排序的限制. 需要考虑是需要索引来排序还是先检索数据再排序,因为使用索引排序会严格限制索引和查询的设计.如果MySQL使用了某个索引的范围查询,也就无法再使用另一个索引或者是该索引的后续字段进行排序了.接下来一步步讨论: 1.支持多种过滤条件 country列的选择性通常不高,但是

高性能的MySQL(7)Query Cache技术详解

MySQL查询缓存保存查询返回的完整结果.当查询命中该缓存,会立刻返回结果,跳过了解析,优化和执行阶段. 查询缓存会跟踪查询中涉及的每个表,如果这写表发生变化,那么和这个表相关的所有缓存都将失效. 但是随着服务器功能的强大,查询缓存也可能成为整个服务器的资源竞争单点. 如何来判断打开查询缓存的好坏呢,就是本篇的内容~~~ 一.如何判断命中缓存 缓存存放在一个引用表中,通过一个哈希值引用,这个哈希值包括查询本身,数据库,客户端协议的版本等,任何字符上的不同,例如空格,注释都会导致缓存不命中. 当查

mysql多表连接和子查询

文章实例的数据表,来自上一篇博客<mysql简单查询>:http://blog.csdn.net/zuiwuyuan/article/details/39349611 MYSQL的多表连接建立在有相互关系的父子表上,分为交叉连接.内连接.外连接.自连接 一. 交叉连接/笛卡尔交集 SELECT COUNT(*) FROM emp; # 返回14行 SELECT COUNT(*) FROM dept; #返回4行 SELECT COUNT(*) FROM emp,dept; #返回14*4=56

mysql char类型主键做查询、更新条件时遇见怪事了,求大神解答

问题描述 mysql char类型主键做查询.更新条件时遇见怪事了,求大神解答 mysql> desc card_info; +-------------+-----------+------+-----+-------------------+-------+ | Field | Type | Null | Key | Default | Extra | +-------------+-----------+------+-----+-------------------+-------+ |

mysql data列表数据和select查询数据不符

问题描述 mysql data列表数据和select查询数据不符 通过data列表插入的数据和在查询select到的数据不符,data列表不能刷新,请大神解答一下= = 解决方案 要么你插入语句有问题,要么你查询语句有问题 解决方案二: 挨个排除呗,先插入一条,自己去数据库看看有没有插入进去,有的话说明你插入语句没问题:然后再查询,如果和数据库里面的不符,肯定是你查询语句的问题了 解决方案三: 是没是还没有提交 (commit)

mysql update 根据表中字段查询另一张表更新更新

问题描述 mysql update 根据表中字段查询另一张表更新更新 mysql有两张表, 班级表class,包含 | id | name | | 1 | 一班 | | 2 | 二班 | 学生表student,其中classId为空,className有值并对应class表中的name | id | name | classId | className | | 1 | 一班 | | 一班 | | 2 | 二班 | | 二班 | | 3 | 一班 | | 一班 | | 4 | 二班 | | 二班