mysql笔记03 查询性能优化

查询性能优化

1. 为什么查询速度会慢?

1). 如果把查询看作是一个任务,那么它由一系列子任务组成,每个子任务都会消耗一定的时间。如果要优化查询,实际上要优化其子任务,要么消除其中一些子任务,要么减少子任务的执行次数,要么让子任务运行的更快。

2). 通常来说,查询的生命周期大致可以按照顺序来看:从客户端,到服务器端,然后在服务器上进行解析,生成执行计划,执行,并返回结果给客户端。其中"执行"可以认为是整个生命周期中最重要的阶段,这其中包括

大量为了检索数据到存储引擎的调用以及调用后的数据处理,包括排序、分组等。

3). 在完成这些任务的时候,查询需要在不同的地方花费时间,包括网络,CPU计算,生成统计信息和执行计划、锁等待(互斥等待)等操作,尤其是向底层存储引擎检索数据的调用操作,这些调用需要在内存中操作、CPU操作

和内存不足时导致的IO操作上消耗时间,根据上下文不同,可能会产生大量的上下文切换以及系统调用。

2. 慢查询基础:优化数据访问

查询性能低下最基本的原因是访问的数据太多。某些查询可能不可避免地需要筛选大量数据,但这并不常见。大部分性能低下的查询都可以通过减少访问的数量的方式进行优化。对于低效查询,可以通过下面两个步骤来分析:

1). 确认应用程序是否在检索大量超过需要的数据。这通常意味着访问了太多的行,但有时候可能是访问了太多的列。

2). 确认MySQL服务器层是否在分析大量超过需要的数据行。

2.1 是否向数据库请求了不需要的数据

1).  一些典型案例

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

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

c. 总是取出全部列:每次看到SELECT * 的时候都需要用怀疑的眼光审视,是不是真的需要返回全部列?取出全部列会让优化器无法完成索引覆盖扫描这类优化,还会为服务器带来额外的网络、IO、内存和

CPU的消耗。

d. 重复查询相同的数据:比较好的方案是,当初次查询的时候将这个数据缓存起来,需要的时候从缓存中取出,这样性能会更好。

2.2 MySQL是否在扫描额外的记录:

1). 对于MySQL,最简单的衡量查询开销的三个指标如下:

a. 响应时间:响应时间是两部分之和:服务时间和排队时间。服务时间是指数据库处理这个查询真正花多长时间。排队时间是指服务器因为等待某些资源而没有真正执行查询的时间--可能是等IO操作完成,也可能

是等待行锁等等。

b. 扫描的行数和返回的行数:分析查询时,查看该查询扫描的行数是非常有帮助的。这在一定程度上能够说明该查询找到需要的数据的效率高不高。

c. 扫描的行数和访问类型:在评估查询开销的时候,需要考虑一下从表中找到某一行数据的成本。MySQL有好几种访问方式可以查询并返回一行结果。有些方式可能需要扫描很多行才能返回一行结果,也有些访问

方式可能无需扫描就能返回结果。

在EXPALIN语句中的type列反应了访问类型。访问类型有很多种,从全表扫描到索引扫描、范围扫描、唯一索引扫描、常数引用等。这里列的这些,速度是从慢到快,扫描的行数是从多到少。你不要记住这

些访问类型,但需要明白扫描表、扫描索引、范围访问和单值访问的概念。

2). 一般MySQL能使用如下三种方式应用WHERE条件,从好到坏依次为:

a. 在索引中使用WHERE条件来过滤不匹配的记录。这是在存储引擎层完成的。

b. 使用索引覆盖扫描(在Extra列中出现Using index)来返回记录,直接从索引中过滤不需要的记录并返回命中的结果。这是在MySQL服务器层完成的,但无需再回表查询记录。

c. 从数据表中返回数据,然后过滤掉不满足条件的记录(在Extra列中出现Using Where)。这在MySQL服务器层完成,MySQL需要先从数据表读取记录然后过滤。

3). 如果发现查询需要扫描大量的数据但只返回少数的行(使用聚合函数等),那么通常可以尝试下面的技巧去优化它们:

a. 使用索引覆盖扫描,把所有需要用的列都放到索引中,这样存储引擎无需回表获取对应行就可以返回结果了。

b. 改变库表结构。例如使用单独的汇总表。

c. 重写这个复杂的查询,让MySQL优化器能够以更优的方式执行这个查询。

3. 重构查询的方式:有时候,可以将查询转换一种写法让其返回一样的结果,但性能更好。

3.1 一个复杂查询还是多个简单查询

a. 设计查询的时候一个需要考虑的重要问题是,是否需要将一个复杂的查询分成过个简单的查询。在传统实现中,总是强调需要数据库层完成尽可能多的工作,这样做的逻辑在于以前总是认为网络通信、

查询解析和优化是一件代价很高的事情。但是这样的想法对于MySQL并不适用,MySQL从设计上让连接和断开连接都很轻量级,在返回一个小的查询结果方面很高效。现代的网络速度比以前要快的多,

无论是带宽还是延迟。

b. MySQL内部每秒能够扫描内存中上百万行数据,相比之下,MySQL响应数据给客户端就慢得多了。在其他条件都相同的时候,使用尽可能少的查询当然是更好的。但是有时候,将一个大查询分解成

多个小查询也是很有必要的。

3.2 切分查询:删除旧数据是一个很好的例子。定期清除大量数据时,乳沟用一个大的语句一次性删除完成的话,则可能需要一次锁住很多数据、占满整个事务日志、耗尽系统资源、阻塞很多小的但很重要的查询。

同时需要注意,如果每次删除数据后,都暂停一会再做下一次删除,可以经服务器压力分散到很长的时间段中。

3.3 分解关联查询:

分解关联查询的方式重构查询有如下的优势:

a. 让缓存的效率更高。许多应用程序可以方便地使用缓存单表查询对应的结果集。

b. 将查询分解后,执行单个查询可以减少锁的竞争。

c. 在应用层做关联,可以更容易对数据库进行拆分,更容易做到高性能和可扩展性。

d. 查询本身效率也可能会有所提升。

e. 可以减少冗余记录的查询。管理查询中可能需要重复地访问一部分数据。

f. 更进一步,这样做相当于在应用中实现了哈希关联,而不是使用MySQL的嵌套循环关联。某些场景哈希关联的效率要高很多。

4. 查询执行的基础:

查询执行的过程:

1). 客户单发送一条查询给服务器

2). 服务器检查查询缓存,如果命中了缓存,则立刻返回存储在缓存中的结果。否则进入下一阶段。

3). 服务器端进行SQL解析、预处理,再由优化器生成对应的执行计划。

4). MySQL根据优化器生成的执行计划,调用存储引擎的API来执行查询。

5). 将结果返回给客户端。

时间: 2024-12-11 04:04:38

mysql笔记03 查询性能优化的相关文章

【MVC+MySQL+EntityFramework】查询性能优化笔记

通过在DbContext中定了表之间的关系,查询后在View中通过item.ProjectOverHour来显示关联表数据. modelBuilder.Entity<ProjectOverHour>() .HasMany(e => e.DailyReports) .WithRequired(e => e.ProjectOverHour) .HasForeignKey(e => new { e.ProjectIndex, e.EmployeeId, e.ReportDate }

170727、MySQL查询性能优化

MySQL查询性能优化 MySQL查询性能的优化涉及多个方面,其中包括库表结构.建立合理的索引.设计合理的查询.库表结构包括如何设计表之间的关联.表字段的数据类型等.这需要依据具体的场景进行设计.如下我们从数据库的索引和查询语句的设计两个角度介绍如何提高MySQL查询性能. 数据库索引 索引是存储引擎中用于快速找到记录的一种数据结构.索引有多种分类方式,按照存储方式可以分为:聚簇索引和非聚簇索引:按照数据的唯一性可以分为:唯一索引和非唯一索引:按照列个数可以分为:单列索引和多列索引等.索引也有多

高性能mysql 第六章查询性能优化 总结(上)查询的执行过程

6  查询性能优化 6.1为什么查询会变慢 这里说明了的查询执行周期,从客户端到服务器端,服务器端解析,优化器生成执行计划,执行(可以细分,大体过程可以通过show profile查看),从服务器端返回客户端结果. 而执行部分作为最重要的一环,需要做的事情比较多,而不合适的query往往让执行过程做了不必要的操作,或者不能使用更优秀的底层数据结构,从而用时更久. 6.2慢查询基础:优化数据访问 访问数据量多大,超过实际所需是慢查询的一个原因.导致这种情况的原因大致有两个 1.应用程序向mysql

mysql分解连接的总结(来自于高性能MySQL以及自己网站性能优化)

许多高性能的站点都用了"分解连接"技术,也就是把单个多表连接查询改成多个但表查询,然后在程序中合并数据,比如: select a.*,b.* from A a join B b on a.id = b.id 可以替换为: select a.* from A; select b.* from B; 然后再把数据通过程序合并. 可能有些人认为这太浪费了,把一个查询语句变成两条查询语句或者更多的查询语句了,如果哪位猿类这样想了,那你就应该继续往下看了. 将连接查询重构为多表查询,总体有以下性

查询性能优化

查询性能优化 怎么样算查询性能比较好?响应时间短(获取查询数据速度快) 优化数据访问 查询性能低下最基本的原因是访问的数据太多.大部分性能低下的查询都可以通过减少访问的数据量的方式进行优化. 对于低效的查询,我们发现通过下面两个步骤来分析总是很有效: 确认应用程序是否在检索大量超过需要的数据.这通常意味着访问了太多行,但有时候也可能是访问了太多的列. 确认MySQL服务器层是否在分析大量超过需要的数据行. 总结:1.只查询了需要的列2.在满足要求的前提下尽可能扫描少的行 是否向数据库请求了不需要

SET STATISTICS IO和SET STATISTICS TIME 在SQL Server查询性能优化中的作用

原文:SET STATISTICS IO和SET STATISTICS TIME 在SQL Server查询性能优化中的作用 近段时间以来,一直在探究SQL Server查询性能的问题,当然也漫无目的的查找了很多资料,也从网上的大神们的文章中学到了很多,在这里,向各位大神致敬.正是受大神们无私奉献精神的影响,所以小弟也作为回报,分享一下关于SET STATISTICS IO和SET STATISTICS TIME这两条T_SQL命令,在查询优化性能中的作用. 首先我想说明一下这篇文章不是关于如何

mongodb 学习笔记 03 -- 查询表达式

mongodb 学习笔记 03 – 查询表达式 不等于,大于,小于 !=: db.stu.find({name:{$ne:'billvsme'}}) 名字不是'billvsme' > : db.stu.find({age:{$gt:18}}) 年纪大于18 < : db.stu.find({age:{$lt:18}}) 年纪小于18 >=: $gte <=: $lte in/not in/all $in :db.goods.find(stu_id:{$in:[93001,93002

SQL Server 查询性能优化 相关文章

来自: SQL Server 查询性能优化——堆表.碎片与索引(一) SQL Server 查询性能优化——堆表.碎片与索引(二) SQL Server 查询性能优化——覆盖索引(一) SQL Server 查询性能优化——覆盖索引(二) SQL Server 查询性能优化——创建索引原则(一) SQL Server 查询性能优化——创建索引原则(二) SQL Server 查询性能优化——索引与SARG(一) SQL Server 查询性能优化——索引与SARG(二) SQL Server 查

SQl语句查询性能优化

[摘要]本文从DBMS的查询优化器对SQL查询语句进行性能优化的角度出发,结合数据库理论,从查询表达式及其多种查询条件组合对数据库查询性能优化进行分析,总结出多种提高数据库查询性能优化策略,介绍索引的合理建立和使用以及高质量SQL查询语句的书写原则,从而实现高效的查询,提高系统的可用性. [关键词]SQL查询语句,索引,性能优化 1.引言 在应用系统开发初期,由于开发数据库数据比较少,对于查询SQL语句,索引的运用与复杂视图的编写等体会不出SQL语句各种写法的性能优劣,但是应用系统实际应用后,随