在编写快速的查询之前,需要清楚一点,真正重要是影响时间。如果把查询看作是一个任务,那么它由一系列子任务组成,每个子任务都会消耗一定的时间。如果要优化查询,实际上要优化其子任务,要么消除其中一些子任务,那么减少子任务的执行次数,要么让子任务运行得更快。
通常来说,查询的生命周期大致可以按照顺序来看:从客户端,到服务器,然后在服务器上进行解析,生成执行计划,执行,并返回结果给客户端。其中“执行”可以认为是整个生命周期中最重要的阶段,这其中包括了大量为了检索数据到存储引擎的调用以及调用后的数据处理,包括排序、分组等。
在完成这些任务的时候,查询需要在不同的地方花费时间,包括网络,CPU计算,生成统计信息和执行计划、锁等待(互斥等待)等操作,尤其是向底层存储引擎检索数据的调用操作,这些调用需要在内存操作、CPU操作和内存不足时导致的I/O操作上消耗时间。根据存储引擎不同,可能还会产生大量的上下文切换以及系统调用。
在每一个消耗大量时间的查询案例中,都看到一些不必要的额外操作、某些操作被额外的重复了很多次、某些操作执行的太慢等。优化查询的目的就是减少和消除这些操作所花费的时间。
1、优化数据访问
查询性能低下最基本的原因是访问的数据太多。某些查询不可避免的需要筛选大量数据,但这并不常见。大部分性能低下的查询都可以通过减少访问的数据量的方式进行优化。对于低效的查询,我们发现通过下面两个步骤来分析总是很有效:
- 确认应用程序是否在检索大量超过需要的数据。这通常意味着访问了太多的行,但有时候可能访问了太多的列。例如一下案例:查询不需要的记录;多表关联时返回全部列;总是取出全部列;重复查询相同的数据;
- 确认mysql服务器层是否在分析大量超过需要的数据行。对于mysql,最简单的衡量查询开销的三个指标如下:影响时间;扫描的行数;返回的行数;
注意:①相应时间是两部分之和:服务时间和排队时间。服务时间是指数据库处理这个查询真正花了多长时间。排队时间是指服务器因为等待某些资源而没有真正执行查询的时间----可能是等I/O操作完成,也可能是等待行锁。
②在EXPLAIN语句中的type列反应了访问类型。访问类型有很多种,从全表扫描到索引扫描、范围扫描、唯一索引查询、常数引用等。这里列的这些,从速度从慢到快,扫描的行数也是从小到大。如果查询没有办法找到合适的访问类型,那么解决的最好办法通常就是增加一个合适的索引,索引让mysql以最高效、扫描行数最小的方式找到所需要的记录。
2、一般mysql使用where条件的方式
- 在索引中使用where条件来过滤不匹配的记录。这是在存储引擎层完成的;
- 使用索引覆盖扫描(在extra列中出现了Using index)来返回记录,直接从索引中过滤不需要的记录并返回命中的结果。这是在mysql服务器层完成的,但无须在返回表查询记录;
- 从数据表中返回数据,然后过滤不满足条件的记录(在extra列中出现Using Where)。这在mysql服务器层完成,mysql需要先从数据表读出记录然后过滤。
3、如果查询扫描大量数据单返回少数行,则通过下面技巧优化
- 使用索引覆盖扫描,把所有需要用的列都放到索引中,这样存储引擎无须回表获取对应行就可以返回结果了。
- 改变数据库表结构。例如使用单独的汇总表。
- 重写这个复杂的查询,让mysql优化器能够以更优化的方式执行这个查询。
4、重构查询的方式
- 一个复杂查询还是多个简单查询。mysql在设计上让连接和断开都很轻量级,在返回一个小的查询结果方面很高效。mysql内部每秒能够扫描内存中的百万行数据,相比下,mysql响应数据给客户端的就慢的多了。有时候将一个大查询分解为多个小查询很有必要。不过,在应用设计的时候,如果一个查询能够胜任是还写成多个独立的查询是很不明智的。
- 切分查询。有时候对于一个大查询我们需要“分而治之”,将大查询切分成小查询,每个查询功能完全一样,只完成一小部分,每次都返回一个小部分查询结果。例如:删除旧数据,定期清理大数据时,用一个大语句需要锁定太多的资源,阻塞其他查询,但是切分后,就可以减少资源的占有。
- 分解关联查询。可以对每一个表进行一次单表查询,然后将结果在应用程序中进行关联。分解关联查询有如下优势:让缓存的效率更高;将查询分解后,执行单个查询可以减少锁的竞争;在应用层做关联,可以更容易对数据库进行拆分,更容易做到高性能和扩展;查询本身效率也可能会有提升;可以减少冗余记录的查询;更进一步,这样做相当于在应用中实现了哈希关联,而不是使用mysql的嵌套循环关联。
5、mysql查询优化器的局限性
mysql的万能“嵌套循环”并不是对每种查询都是最优的。不过还好,mysql查询优化器只对少部分不适用,而且我们往往可以通过改写查询让mysql高效的完成工作。
- 关联子查询:mysql的子查询实现的非常糟糕。最糟糕的一类查询是where条件中包含IN()的子查询语句。例如:我们希望找到sakila数据库中,演员Penelope guiness参演过的所有影片信息,我们一般会如下查询:select * from sakila.film where film_id in (select film_id from sakila.film_actor where actor_id=1); 一般会认为mysql会先执行子查询返回包含actor_id为1的film_id。一般来说,in列表查询速度也很快。但很不幸,mysql不是这样做的,mysql会将查询修改成下面样子:select * from sakila.film where exists (select * from sakila.film_actor where actor_id=1 and film_actor.film_id=film.film_id);这时子查询需要根据film_id来关联外部表film。通过EXPLAIN我们可以看到,mysql选择对film表进行全表扫描,那么这个查询的性能会非常糟糕。当然我们可以重写这个查询:select film.* from sakila.film inner join saila.film_actor using (film_id) where actor_id=1;
- 如何用好关联子查询:并不是所有关联子查询的性能都会很差。很多时候,关联子查询是一种非常合理、自然,甚至是性能最好的写法。
- 有时候mysql无法将限制条件从外层“下推”到内层,这使得原本能够限制部分返回结果的条件无法应用到内层查询的优化上。例如:如果希望union的各个子句能够根据limit只取部分结果集,或者希望能够先排好序在合并结果集的话,就需要在union的各个子句中分别使用这些子句。
- 当where子句中包含多个复杂条件的时候,mysql能够访问单个表的多个索引以合并和交叉过滤的方式来定位需要查找的行。
- mysql无法利用多核特性来执行查询。很多其他的关系型数据库能够提供这个特性,但是mysql做不到。并且当前mysql还不支持哈希关联和松散索引扫描
- mysql对于min()和max()查询,mysql的优化做的并不好,例如:select min(actor_id) from sakila.actor where first_name = 'penelope';因为在first_name字段上并没有索引,因此mysql将会进行一次全表扫描。如果mysql能够进行主键扫描,理论上当mysql读到第一个满足条件记录的时候,就是我们所需的最小值了,因为主键是严格按照actor_id字段的大小顺序排列的。但mysql这时只会做全表扫描。
- mysql不允许对同一张表同时进行查询和更新。但可以通过临时表的形式处理。
相关推荐
优化查询语句是 MySQL 查询性能优化的另一个重要方面。优化查询语句可以减少查询时间、提高查询效率。MySQL 提供了多种查询优化技术,包括使用 UNION 优化、使用子查询优化、使用 JOIN 优化等。 6.3 MySQL 查询优化...
### 高性能MySQL查询性能优化知识点详解 #### 一、查询性能优化的重要性 在数据库管理与维护工作中,查询性能优化是提升系统响应速度、降低服务器负载的重要手段之一。随着业务量的增长,数据库面临的查询压力也...
MySQL性能优化是指通过调整MySQL数据库的配置、优化数据库结构和查询语句等方式,提高MySQL数据库的性能和响应速度,以满足应用程序的需求。MySQL作为最流行的开源数据库之一,被广泛应用于各种规模的企业和应用程序...
"基于MySQL的数据库查询性能优化" 在当前的Web应用开发中,数据库的查询操作已经成为整个应用的性能瓶颈, especialmente 对于使用 MySQL 的 Web 应用。因此,数据库查询性能的优化已经成为一个非常重要的课题。...
### 释放MySQL性能:优化查询的艺术 #### 一、引言:查询性能优化的重要性 在当今数据驱动的时代,数据库管理成为任何业务成功的关键因素之一。MySQL作为一种流行的关系型数据库管理系统(RDBMS),广泛应用于各类...
MySQL的SQL查询性能优化技术是数据库管理中至关重要的一环,对于提升系统效率和用户体验有着显著影响。本篇主要探讨了优化SQL查询的一些基本原则、企业级监控、配置与参数化、数据管理和性能考量等方面。 首先,...
MySQL性能优化是一个涵盖广泛的主题,涉及多个层面,包括SQL语句优化、索引优化、数据库表结构优化、系统级配置优化以及服务器硬件优化。以下是对这些方面进行详细说明: 1. **SQL语句优化** - **慢查询日志**:...
基于 MySQL 数据库的查询性能优化研究 MySQL 数据库是当前网络环境中最流行的开源关系型数据库之一,随着网络环境中数据总量的急剧攀升,对数据库查询的响应时间提出了更严格的要求。为了提高查询效率,需要研究 ...
MySQL 数据库性能优化研究 MySQL 数据库性能优化是当前数据库管理系统中最重要的研究领域之一。随着互联网技术的快速发展,MySQL 数据库被广泛应用于各种业务场景。然而,当数据库规模不断扩大,查询复杂度增加时,...
本书深入浅出地讲解了MySQL性能优化的核心原理,包括索引设计、查询优化、缓存策略、高可用架构等方面的知识。同时,结合案例对这些原理进行了生动形象的阐述,方便读者理解和实践。 实践过程 本书详细描述了优化...
本文将围绕《构建高性能Web站点》一书中有关MySQL性能优化的部分内容进行详细解读,帮助读者更好地理解和掌握MySQL性能优化的方法和技术。 #### 二、友好的状态报告与正确使用索引 ##### 1. 友好的状态报告 - **...
总结,MySQL性能优化与架构设计涵盖了许多方面,包括查询优化、索引策略、数据库设计、缓存利用、并行处理、架构设计、数据分布以及监控与调优工具的使用。理解和掌握这些知识点,能够帮助我们构建高效、稳定的...
通过对my.cnf/my.ini配置文件的各项关键参数进行中文注释与解析,帮助DBA及运维人员更好地理解每个配置项的作用及其对MySQL性能的影响。 #### 关键配置项详解 ##### 1. **[client]** - **port=3306**:设定MySQL...
MySQL性能优化是数据库管理员和开发人员的关键技能,它涉及到如何有效地使用SQL语句、存储过程和函数,以提高数据查询速度和系统整体效率。本手册将深入探讨这些关键领域,帮助你理解并实施最佳实践。 在SQL语句...
总之,MySQL性能优化是一个综合性的过程,需要结合理论知识和实践经验,通过对查询优化、索引设计、系统配置等方面的调整,以达到提升系统性能的目标。在高并发环境下,合理的优化策略可以显著提高系统的响应速度和...
MySQL性能优化是一个综合性的过程,涉及到SQL查询优化、数据库结构优化以及MySQL服务器配置等多个方面。通过上述方法和技术的应用,可以显著提高MySQL的运行效率,降低资源消耗,最终实现更好的用户体验和服务质量。
两小时解决所有问题--MySQL数据库性能优化
MySQL是世界上最受欢迎的开源关系型数据库之一,尤其在处理海量数据时,其性能优化显得尤为重要。本资料"海量数据性能优化.rar"主要聚焦于如何在大数据环境下提升MySQL的运行效率和响应速度,确保系统的稳定性和可...