前提介绍 为何分页查询在测试环境没事,在生产上几千万的数据就出现了问题 在平时开发时,由于数据量没有那么大,所以测试有时候会不到位,比如用到的分页查询,使用不规范时,数据量越大,查询越慢,而且有 长时间进程不结束 对limit的优化,不是直接使用limit,而是首先获取到offset的id,然后直接使用limit size来获取数据。 1、尽量给出查询的大致范围 SELECT c1,c2,cn… FROM table WHERE id>=20000 LIMIT 10; 2、子查询法 SELECT c1,c2,cn… FROM table member ORDER BY last_active LIMIT 50,5 优化后SQL: SELECT c1, c2, cn .. . 而优化后的SQL(子查询那条)只读索引(Cover index)就可以了,然后通过member_id读取需要的列。
一、问题背景 现网出现慢查询,在500万数量级的情况下,单表查询速度在30多秒,需要对sql进行优化,sql如下: 我在测试环境构造了500万条数据,模拟了这个慢查询。 三、优化 说实话,我是不知道该怎么优化的,这玩意还能怎么优化啊!先说下,下面的思路都是没用的。 思路二: where条件太复杂,没索引,导致查询慢,但我给where条件的所有字段加上了组合索引,也还是没用 思路三: 既然group by慢,换distinct试试?? 那就是sqlyog的问题了,现在也不清楚sqlyog是不是做什么优化了,这个慢查询的问题还在解决中(我觉得问题可能是出在mysql自身的参数上吧)。 五、后续(还未解决) 感谢大家出谋划策,我来回复下问题进展: 1.所谓的sqlyog查询快,命令行查询慢的现象,已经找到原因了。
定位低效 SQL 执行慢有两种情况: 偶尔慢:DB 在刷新脏页 redo log 写满了 内存不够用,要从 LRU 链表中淘汰 MySQL 认为系统空闲的时候 MySQL 关闭时 一直慢的原因 :索引没有设计好、SQL 语句没写好、MySQL 选错了索引 ’mysql慢查询优化 第一步:开启mysql慢查询日志,通过慢查询日志定位到执行较慢的SQL语句。 第二步:利用explain关键字可以模拟优化器执行SQL查询语句,来分析SQL查询语句。 第三步:通过查询的结果进行优化。 优化方式 (1)首先分析语句,看看是否包含了额外的数据,可能是查询了多余的行并抛弃掉了,也可能是加了结果中不需要的列,要对SQL语句进行分析和重写。 (2)分析优化器中索引的使用情况,要修改语句使得更可能的命中索引。比如使用组合索引的时候符合最左前缀匹配原则。not in,not like都不会走索引,可以优化为in.
这篇文章主要是就在公司实习的时候,对SQL优化工作作出的一些整理。 在公司实习的时候,导师分配了SQL慢查询优化的任务,任务是这样的:每周从平台中导出生产数据库的慢查询文件进行分析。 (1)数据库中设置SQL慢查询 一、第一步.开启mysql慢查询 方式一: 修改配置文件 在 my.ini 增加几行: 主要是慢查询的定义时间(超过2秒就是慢查询 ),以及慢查询log日志记录( slow_query_log) 方法二:通过MySQL数据库开启慢查询: (2)分析慢查询日志 直接分析mysql慢查询日志 ,利用explain关键字可以模拟优化器执行SQL查询语句,来分析sql慢查询语句 例如:执行EXPLAIN SELECT * FROM res_user ORDER BYmodifiedtime const、eq_reg、ref、range、indexhe和ALL rows 显示需要扫描行数 key 使用的索引 (3)常见的慢查询优化
3、慢查询的优化案例 1、函数Max()的优化 用途:查询最后支付时间-优化max()函数 语句: select max(payment_date) from payment; ? 可以看到显示的执行计划,并不是很高效,可以拖慢服务器的效率,如何优化了? 创建索引 create index inx_paydate on payment(payment_date); ? ? 索引是顺序操作的,不需要扫描表,执行效率就会比较恒定, 2、函数Count()的优化 需求:在一条SQL中同时查处2006年和2007年电影的数量 错误的方式: 语句: select count(release_year
1、查看mysql的慢查询日志是否开启 show variables like ‘%query%’; 可以看到slow_query_log的值是OFF,也就是mysql默认是不启用慢查询日志的。 这里还有个long_query_time,默认是10秒,也就是超过了10秒即为慢查询。 log_queries_not_using_indexes,如果设置为ON,则会将所有没有使用索引的查询都记录为慢查询。 2、如何启用慢查询日志呢? select sleep(11); 查看TABLE记录的慢日志: select * from mysql.slow_log; 这里面记录了查询时间、发起查询的客户端、扫描行数、执行的sql语句等信息 查看FILE记录的慢日志: 先找到日志文件 打开文件,查看记录的内容: 版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。
Mysql慢查询设置 分析MySQL语句查询性能的方法除了使用 EXPLAIN 输出执行计划,还可以让MySQL记录下查询超过指定时间的语句,我们将超过指定时间的SQL语句查询称为“慢查询”。 mysql> show variables like ‘long%’; 注:这个long_query_time是用来定义慢于多少秒的才算“慢查询” +—————–+———–+ | Variable_name mysql慢查询日志对于跟踪有问题的查询非常有用,可以分析出当前程序里有很耗费资源的sql语句,那如何打开mysql的慢查询日志记录呢? 其实打开mysql的慢查询日志很简单,只需要在mysql的配置文件里(windows系统是my.ini,linux系统是my.cnf)的[mysqld]下面加上如下代码: log-slow-queries Windows: 当你是第一次开启mysql的慢查询,会在你指定的目录下创建这个记录文件,本文就是mysqlslowquery.log,这个文件的内容大致如下(第一次开启MYSQL慢查询的情况下) E:
二、加入索引 对于上面查询,一下子就查了37秒,表没有做任何优化,显然速度还是可以大大提高的。 三、检测慢查询 对于MySql中的慢查询,MySql是有一套成熟的监控日志的。 可以自己配置慢查询监控日志,修改/etc/my.cnf,添加如下配置: log-slow-queries = /data/mysql/logs/sql_slow.log /*指定查询日志路径 重启MySql服务,即可在对应的日志路径下找到慢查询SQL。 另外,MySql对应的慢查询分析软件很多,比如mysqldumpslow等等。大家都可以看看。
order by 优化 using filesort (额外的一次排序) 有两种算法:双路排序、单路排序(根据IO的次数) Mysql4.1之前 默认 使用 双路排序:扫描2次磁盘(1:从磁盘读取排序字段 最好能确定查询的字段 复合索引 不要跨列使用,避免using filesort 保证全部的排序字段 排序的一致性(都是升序 或 降序) SQL排查 -- 慢查询日志 Mysql提供的一种日志记录 ,用于记录mysql响应时间超过阀值的sql语句(超过10秒) 慢查询日志默认是关闭的: 建议是开发调试 打开 ; 最终部署 关闭 检查是否开启 慢查询日志: show variables slow_query_log = 1 slow_query_log_file = /var/lib/mysql/localhost-slow.log 慢查询阀值 SQL: show global status like '%slow_queries%' --------慢查询的sql被记录在了日志中,因此可以通过日志 查看具体的慢SQL
,查看慢查询,show status like 'slow_queries'... ,myisam存储引擎长时间启动需要进行碎片整理 查看慢查询 show status like 'slow_queries'; 查询慢查询时间 (2) const 数据表最多只有一个匹配行,它将在查询开始时被读取,并在余下的査询优化中作为常量对待。const表查询速度很快,因为它们只读取一次。 在解决子查询中经常使用该链接类型的优化。 not exists MySQL在查询时做一个LEFT JOIN优化时,当它在当前表中找到了和前一条记录符合LEFT JOIN条件后,就不再搜索更多的记录了。
前段时间笔者开发某个项目遇到了MySQL性能问题,每张表的数据量都在五千万以上,个别表数据量甚至在一个亿以上,在开发的过程中遇到了非常多的数据库性能优化难点,笔者在开发过程中查询了很多资料,很多查询语句也在优化过程中取得了比较好的效果 只能对索引进行范围查找是MRR的缺陷,于是又有了BKA优化,batch key access join是mysql 5.6提出优化方案,它在关联查询中获取一批rowid,然后将这批rowid进行排序,再回表查找 驱动表优化 文末笔者还想谈一谈表联结中驱动表。Mysql联接优化的目标是尽可能减少nested loop join 总数,关联查询时候,必须以某张表作为驱动表。 mysql查询优化器优先选择小表作为驱动表,小表不仅仅指表的真实行数或者磁盘空间大小,也包括了两个表按照各自条件过滤后的表。 但是mysql查询优化器有时候会判断出错,选择了大表作为驱动表。
一、查询与索引优化分析 在优化mysql时,通常需要对数据库进行分析,常见的分析手段有慢查询日志, EXPLAIN分析查询, profiling分析以及show命令查询系统状态及系统变量 参数,表示向慢查询日志中记录没有使用索引的查询。 慢查询日志开启方法二: 通过命令行设置变量来即时启动慢查询日志 ? 查看慢查询的设置信息 ? 打开慢查询日志文件查看 ? 如果慢查询日志中记录内容很多,可以使用 mysqldumpslow工具(Msql客户端安装自带)来对慢查询日志进行分类汇总。 mysqldumpslow对日志文件进行了分类汇总,显示汇总后摘要结果。 优化上面的慢查询 ? ? 二、explain分析查询 使用explain可以模拟优化器执行sql查询语句,从而知道mysql是如何处理你的sql语句的。
1.慢查询的用途 它能记录下所有执行超过longquerytime时间的SQL语句,帮我们找到执行慢的SQL,方便我们对这些SQL进行优化。 slowquerylog = off,表示没有开启慢查询 slowquerylog_file 表示慢查询日志存放的目录 3.开启慢查询(需要的时候才开启,因为很耗性能,建议使用即时性的) 方式一:(即时性的 6.查询慢查询的次数:show status like 'slow_queries'; ? 在我们重新执行刚刚的查询sql后,查询慢查询的次数会变为8 ? 在生产中,我们会分析查询频率高的,且是慢查询的sql,并不是每一条查询慢的sql都需要分析。 7.慢查询日志分析工具Mysqldumpslow 由于在生产上会有很多慢查询,所以采用上述的方法查看慢查询sql会很麻烦,还好MySQL提供了慢查询日志分析工具Mysqldumpslow。
四.优化 1.slowlog-max-len配置建议:线上建议调大慢查询列表,记录慢查询时Redis会对长命令做截断操作,并不会占用大量内存。 增大慢查询列表可以减缓慢查询被剔除的可能,例如线上可设置为1000以上。 2.slowlog-log-slower-than配置建议:默认值超过10毫秒判定为慢查询,需要根据Redis并发量调整该值。 3.慢查询只记录命令执行时间,并不包括命令排队和网络传输时间。因此客户端执行命令的时间会大于命令实际执行时间。 因为命令执行排队机制,慢查询会导致其他命令级联阻塞,因此当客户端出现请求超时,需要检查该时间点是否有对应的慢查询,从而分析出是否为慢查询导致的命令级联阻塞。 4.由于慢查询日志是一个先进先出的队列,也就是说如果慢查询比较多的情况下,可能会丢失部分慢查询命令,为了防止这种情况发生,可以定期执行slow get命令将慢查询日志持久化到其他存储中(例如MySQL)
为什么查询速度会慢1.慢是指一个查询的响应时间长。一个查询的过程:客户端发送一条查询给服务器服务器端先检查查询缓存,如果命中了缓存,则立可返回存储在缓存中的结果。 将结果返回给客户端2.数据访问是否向数据库请求了不需要的数据是否扫描额外的记录3.查询的方式一个复杂的查询还是多个简单的查询切分查询(将大查询切分成小查询,循环完成小查询)分解关联查询慢查询分析问题SQL 把复杂的SQL分成多个简单SQL并执行,查看具体那个字段会慢,区分度不高。 比如检查要查询的数据表和数据列是否存在等。查询优化器经过前面的步骤生成的语法树被认为是合法的了,并且由优化器将其转化成查询计划。多数情况下,一条查询可以有很多种执行方式,最后都返回相应的结果。 MySQL的查询优化器是一个非常复杂的部件,它使用了非常多的优化策略来生成一个最优的执行计划:重新定义关联表的顺序将外连接转化成内连接使用等价变换规则优化count()、min()、max()预估并转化为常数表达式覆盖索引描述子查询优化提前终止查询等值传播列表
=和in可以乱序,比如a = 1 and b = 2 and c = 3 建立(a,b,c)索引可以任意顺序,mysql的查询优化器会帮你优化成索引可以识别的形式 #3.尽量选择区分度高的列作为索引, ) - 尽量使用短索引 - 使用连接(JOIN)来代替子查询(Sub-Queries) - 连表时注意条件类型需一致 - 索引散列值(重复高的)不适合建索引,例:性别不适合 六 查询优化神器-explain 所以优化语句基本上都是在优化rows。 userinfo3 where email='alex' type: const(走索引) http://blog.itpub.net/29773961/viewspace-1767044/ 七 慢查询优化的基本步骤 =dir\[filename]] # service mysqld restart 三、慢查询日志 启用慢查询日志 # vim /etc/my.cnf [mysqld] log-slow-queries
摘要 排序引起的慢查询,通常不是那么容易发现,经常和数据分布有关系。 往往在业务刚开始时并没有什么问题,但是随着业务的发展,数据分布呈现一种特定的规律,导致了慢查询,或者并不是什么慢查询,但是随着并发请求数增加,数据库的IOPS使用率变高,进一步导致cpu/内存使用率飙高 问题 因为排序引起的问题遇到很多次 例1:某日收到线上cpu告警 然后查看慢sql日志 大量的慢查询指向了这个查询 SELECT id, prize_id, 经过多重定位,发现从库的IOPS使用率快接近100%了,同时发现有些慢查询 "query":{"find":"historyRecord","filter":{"bizId":1234567,"version 查询优化 业务侧避免此类查询 从业务侧分析,是不是需要此类查询。
本人从13年7月份起,一直在美团核心业务系统部做慢查询的优化工作,共计十余个系统,累计解决和积累了上百个慢查询案例。随着业务的复杂性提升,遇到的问题千奇百怪,五花八门,匪夷所思。 本文旨在以开发工程师的角度来解释数据库索引的原理和如何优化慢查询。 慢查询优化 关于MySQL索引原理是比较枯燥的东西,大家只需要有一个感性的认识,并不需要理解得非常透彻和深入。我们回头来看看一开始我们说的慢查询,了解完索引原理之后,大家是不是有什么想法呢? 所以优化语句基本上都是在优化rows。 慢查询优化基本步骤 0.先运行看看是否真的很慢,注意设置SQL_NO_CACHE 1.where条件单表查,锁定最小返回记录表。 写在后面的话 本文以一个慢查询案例引入了MySQL索引原理、优化慢查询的一些方法论;并针对遇到的典型案例做了详细的分析。
一、简介 MySQL的慢查询日志是MySQL提供的一种日志记录,它用来记录在MySQL中响应时间超过阀值的语句,具体指运行时间超过long_query_time值的SQL,则会被记录到慢查询日志中。 默认情况下,Mysql数据库并不启动慢查询日志,需要我们手动来设置这个参数,当然,如果不是调优需要的话,一般不建议启动该参数,因为开启慢查询日志会或多或少带来一定的性能影响。 慢查询日志支持将日志记录写入文件,也支持将日志记录写入数据库表。 开启慢查询日志,可以让MySQL记录下查询超过指定时间的语句,通过定位分析性能的瓶颈,才能更好的优化数据库系统的性能。 long_query_time 查询超过多少秒才记录 三、设置步骤 1.查看慢查询相关参数 ? 开启慢查询设置成功!
一.介绍 慢查询只记录redis执行时间,并不记录redis服务到客户端之间的网络问题。 超过多少毫秒的才被记录 slowlog-log-slower-than=10000 毫秒(1秒=1000毫秒=1000000微秒) =0 则记录所有 <0 则都不记录 redis使用一个列表来记录慢查询条目 [root@linkops ~]# vi /usr/local/redis/redis.confslowlog-max-len=1000 日志有4部分组成 慢查询日志的标识id 发生时间戳 命令耗时 执行命令和参数 查询实例: 1) 1) (integer) 666 2) (integer) 1456786500 3) (integer) 11615 4) 1) "BGREWRITEAOF" 2) 1)