转载请注明出处❤️
作者:测试蔡坨坨
原文链接:caituotuo.top/c56bd0c5.html
你好,我是测试蔡坨坨。
在往期文章中,我们聊过数据库基础知识,可参考「数据库基础,看完这篇就够了!」。
学完数据库基础知识,要想更深入地了解数据库,就需要学习数据库进阶知识,今天我们就先来聊一聊慢SQL查询那些事儿。
在日常工作中,我们经常会遇到数据库慢查询问题,那么我们要如何进行排查呢?
假设一次执行20条SQL,我们如何判断哪条SQL是执行慢的烂SQL,这里就需要用到慢查询日志。
在SQL中,广义的查询就是CRUD操作,而狭义的查询仅仅是SELECT查询操作,而我们所说的慢查询其实指的是广义的查询,包括增删改查,一般是查询,所以称为慢查询。
MySQL提供的一种日志记录,用于记录MySQL中响应时间超过阈值[yù zhí]的SQL语句(也就是long_query_time的值,默认时间是10秒)。
慢查询日志默认是关闭的,开启会消耗一定的性能,一般是开发调优时打开,而部署时会关闭。
执行语句:
show variables like '%slow_query_log';
从以下执行结果可以看出,慢查询日志默认是OFF关闭状态:

开启慢查询日志有两种方式,分别是临时开启和永久开启。
一般使用临时开启,即在内存中开启,MySQL退出就会自动关闭,从而避免过多的性能开销:
set global slow_query_log = 1; // 1表示开启
set global slow_query_log_file="D:/MySQL Server 5.5/slow_query_log.log"; // 日志存储位置

临时开启,重启MySQL服务后慢查询日志会变成OFF状态:
Linux重启MySQL服务:
service mysql restart
Windows重启MySQL服务:
右击开始菜单——计算机管理——找到MySQL服务——重启:
重启后的可以看到慢查询日志变成OFF关闭状态:

通过修改配置文件的方式可以永久开启慢查询日志。
Linux:在 /etc/my.cnf 中追加配置
vi /etc/my.cnf
[mysqld]
slow_query_log=1
slow_query_log_file=/var/lib/mysql/localhost-slow-query-log.log
Windows:D:\MySQL Server 5.5\my.ini
[mysqld]
slow_query_log=1
slow_query_log_file="D:/MySQL Server 5.5/slow_query_log.log"
永久开启后,即使重启MySQL服务,慢查询日志也不会关闭:

show variables like '%long_query_time%';
可以看到默认值是10s:

设置完毕后,需要重新登录MySQL才能生效(注意是重新登录MySQL,不是重启MySQL服务)。
set global long_query_time = 5;

通过修改配置文件的方式可以永久设置阈值(修改完成后需要重启MySQL服务):
[mysqld]
long_query_time=3

执行如下SQL语句休眠4秒,模拟慢SQL:
select sleep(4);
查询超过阈值的SQL的数量:
show global status like '%slow_queries%';
可以看到超过阈值的SQL数为1:

主要有两种方式可以定位到具体的慢SQL语句,分别为查看日志文件和使用mysqldumpslow工具查看。

假设执行了1000条SQL,其中有30条SQL都超过了阈值,如果直接查看日志文件,无法快速定位到具体的SQL,所以需要使用mysqldumpslow工具,通过一些过滤条件,快速查找出慢SQL。
Linux:
mysqldumpslow命令
--help命令查看帮助文档:
mysqldumpslow --help
-s ORDER排序 what to sort by (al, at, ar, c, l, r, t), 'at' is default
al: average lock time
ar: average rows sent
at: average query time
c: count(访问次数)
l: lock time(锁的时间)
r: rows sent(返回的记录数)
t: query time(查询时间)
-r:逆序 reverse the sort order (largest last instead of first)
-l:锁定时间 don't subtract lock time from total time
-g:后面跟一个正则匹配模式,大小写不敏感
-t:top n,即为返回前面多少条的数据
举栗:
获取返回记录最多的3个SQL
mysqldumpslow -s r -t 3 /var/lib/mysql/localhost-slow-query-log.log
获取访问次数最多的3个SQL
mysqldumpslow -s c -t 3 /var/lib/mysql/localhost-slow-query-log.log
按照时间排序,前10条包含left join查询语句的SQL
mysqldumpslow -s t -t 10 -g "left join" /var/lib/mysql/localhost-slow-query-log.log
Windows:
MySQL安装后以后在bin下有mysqldumpslow.pl文件,如果没有可以自行下载。
D:\MySQL Server 5.5\bin\mysqldumpslow.pl:
mysqldumpslow是一个perl脚本,要想在Windows执行,首先需要安装Perl。
安装过程比较简单,从官网 http://strawberryperl.com/ 下载windows安装包,安装完成后通过perl -v命令测试是否安装成功,如果能显示版本号,表示安装成功。
百度网盘:
链接:https://pan.baidu.com/s/1MiJ3FNUGEoSE1U6dJzOsAg
提取码:slt7
查看帮助文档:
perl mysqldumpslow.pl --help
举栗:
获取返回记录最多的3个SQL
perl mysqldumpslow.pl -s r -t 3 "D:/MySQL Server 5.5/slow_query_log.log"
获取访问次数最多的3个SQL
perl mysqldumpslow.pl -s c -t 3 "D:/MySQL Server 5.5/slow_query_log.log"
按照时间排序,前10条包含left join查询语句的SQL
perl mysqldumpslow.pl -s t -t 10 -g "left join" "D:/MySQL Server 5.5/slow_query_log.log"
我正在用Ruby编写一个简单的程序来检查域列表是否被占用。基本上它循环遍历列表,并使用以下函数进行检查。require'rubygems'require'whois'defcheck_domain(domain)c=Whois::Client.newc.query("google.com").available?end程序不断出错(即使我在google.com中进行硬编码),并打印以下消息。鉴于该程序非常简单,我已经没有什么想法了-有什么建议吗?/Library/Ruby/Gems/1.8/gems/whois-2.0.2/lib/whois/server/adapters/base.
我知道我可以指定某些字段来使用pluck查询数据库。ids=Item.where('due_at但是我想知道,是否有一种方法可以指定我想避免从数据库查询的某些字段。某种反拔?posts=Post.where(published:true).do_not_lookup(:enormous_field) 最佳答案 Model#attribute_names应该返回列/属性数组。您可以排除其中一些并传递给pluck或select方法。像这样:posts=Post.where(published:true).select(Post.attr
目录第1题连续问题分析:解法:第2题分组问题分析:解法:第3题间隔连续问题分析:解法:第4题打折日期交叉问题分析:解法:第5题同时在线问题分析:解法:第1题连续问题如下数据为蚂蚁森林中用户领取的减少碳排放量iddtlowcarbon10012021-12-1212310022021-12-124510012021-12-134310012021-12-134510012021-12-132310022021-12-144510012021-12-1423010022021-12-154510012021-12-1523.......找出连续3天及以上减少碳排放量在100以上的用户分析:遇到这类
我正在尝试查询我的Rails数据库(Postgres)中的购买表,我想查询时间范围。例如,我想知道在所有日期的下午2点到3点之间进行了多少次购买。此表中有一个created_at列,但我不知道如何在不搜索特定日期的情况下完成此操作。我试过:Purchases.where("created_atBETWEEN?and?",Time.now-1.hour,Time.now)但这最终只会搜索今天与那些时间的日期。 最佳答案 您需要使用PostgreSQL'sdate_part/extractfunction从created_at中提取小时
我在Rails上使用带有ruby的solr。一切正常,我只需要知道是否有任何现有代码来清理用户输入,比如以?开头的查询。或* 最佳答案 我不知道执行此操作的任何代码,但理论上可以通过查看parsingcodeinLucene来完成并搜索thrownewParseException(只有16个匹配!)。在实践中,我认为您最好只捕获代码中的任何solr异常并显示“无效查询”消息或类似信息。编辑:这里有几个“sanitizer”:http://pivotallabs.com/users/zach/blog/articles/937-s
我正在为锦标赛开发一个Rails应用程序。我在这个查询中使用了三个模型:classPlayertruehas_and_belongs_to_many:tournamentsclassTournament:destroyclassPlayerMatch"Player",:foreign_key=>"player_one"belongs_to:player_two,:class_name=>"Player",:foreign_key=>"player_two"在tournaments_controller的显示操作中,我调用以下查询:Tournament.where(:id=>params
我想用sunspot重现以下原始solr查询q=exact_term_text:fooORterm_textv:foo*ORalternate_text:bar*但我无法通过标准的太阳黑子界面理解这是否可能以及如何实现,因为看起来:fulltext方法似乎不接受多个文本/搜索字段参数我不知道将什么参数作为第一个参数传递给fulltext,就好像我通过了"foo"或"bar"结果不匹配如果我传递一个空参数,我得到一个q=*:*范围过滤器(例如with(:term).starting_with('foo*')(顾名思义)作为过滤器查询应用,因此不参与评分。似乎可以手动编写字符串(或者可能使
例如,假设我有一个名为Products的模型,并且在ProductsController中,我有以下代码用于product_listView以显示已排序的产品。@products=Product.order(params[:order_by])让我们想象一下,在product_listView中,用户可以使用下拉菜单按价格、评级、重量等进行排序。数据库中的产品不会经常更改。我很难理解的是,每次用户选择新的order_by过滤器时,rails是否必须查询,或者rails是否能够以某种方式缓存事件记录以在服务器端重新排序?有没有一种方法可以编写它,以便在用户排序时rails不会重新查询结果
我找到了这样的东西:Rails:Howtolistdatabasetables/objectsusingtheRailsconsole?这一行没问题:ActiveRecord::Base.connection.tables并返回所有表但是ActiveRecord::Base.connection.table_structure("users")产生错误:ActiveRecord::Base.connection.table_structure("projects")我认为table_structure不是Postgres方法。如何列出Postgres数据库的Rails控制台中表中的所有
我目前正在尝试了解RoR。我将两个字符串传递到我的Controller中。一个是随机的十六进制字符串,另一个是电子邮件。该项目用于对数据库进行简单的电子邮件验证。我遇到的问题是当我输入如下内容来测试我的页面时:http://signup.testsite.local/confirm/da2fdbb49cf32c6848b0aba0f80fb78c/bob.villa@gmailcom我在:email的参数散列中得到的全部是'bob'。我在gmail和com之间留下了.,因为那样会导致匹配根本不起作用。我的路由匹配如下:match"confirm/:code/:email"=>"conf