高性能的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、不要总是取出全部的列 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.cn/database/MySQL/ (编辑:徐州站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |