如何查找MySQL中查询慢的SQL语句

如何查找MySQL中查询慢的SQL语句,第1张

问题

我们有一个 SQL,用于找到没有主键 / 唯一键的表,但是在 MySQL 57 上运行特别慢,怎么办

实验

我们搭建一个 MySQL 57 的环境,此处省略搭建步骤。

写个简单的脚本,制造一批带主键和不带主键的表:

执行一下脚本:

现在执行以下 SQL 看看效果:

执行了 1680s,感觉是非常慢了。

现在用一下 DBA 三板斧,看看执行计划:

感觉有点惨,由于 information_schemacolumns 是元数据表,没有必要的统计信息。

那我们来 show warnings 看看 MySQL 改写后的 SQL:

我们格式化一下 SQL:

可以看到 MySQL 将

select from A where Ax not in (select x from B) //非关联子查询

转换成了

select from A where not exists (select 1 from B where Bx = ax) //关联子查询

如果我们自己是 MySQL,在执行非关联子查询时,可以使用很简单的策略:

select from A where Ax not in (select x from B where ) //非关联子查询:1 扫描 B 表中的所有记录,找到满足条件的记录,存放在临时表 C 中,建好索引2 扫描 A 表中的记录,与临时表 C 中的记录进行比对,直接在索引里比对,

而关联子查询就需要循环迭代:

select from A where not exists (select 1 from B where Bx = ax and ) //关联子查询扫描 A 表的每一条记录 rA:     扫描 B 表,找到其中的第一条满足 rA 条件的记录。

显然,关联子查询的扫描成本会高于非关联子查询。

我们希望 MySQL 能先"缓存"子查询的结果(缓存这一步叫物化,MATERIALIZATION),但MySQL 认为不缓存更快,我们就需要给予 MySQL 一定指导。

可以看到执行时间变成了 067s。

整理

我们诊断的关键点如下:

\1 对于 information_schema 中的元数据表,执行计划不能提供有效信息。

\2 通过查看 MySQL 改写后的 SQL,我们猜测了优化器发生了误判。

\3 我们增加了 hint,指导 MySQL 正确进行优化判断。

但目前我们的实验仅限于猜测,猜中了万事大吉,猜不中就无法做出好的诊断。

1、打开Microsoft SQL Server 2012,选中需要查询所有表的数据库。

2、选中需要查询的表后,点击左上角的“新建查询”,如图。

3、点击“新建查询”后,会在右边d出一个编辑框,我们需要在这里编写sql语句,来查询该数据库下的所有表结构。

4、编写sql语句,点击“执行”,当然,这表语句我们可以根据实际情况,来改变条件只查询需要的表名。

5、这时,会在右下方出现最终的查询结果,name即该库下所有的表名。

可用group by…having来实现。

可做如下测试:

1、创建表插入数据:

create table test
(id int,
name varchar(10))
insert into test values (1,'张三')
insert into test values (2,'李四')
insert into test values (3,'张三')
insert into test values (4,'王五')
insert into test values (5,'赵六')

其中name是张三的有两行,也就是重复行。

2、执行sql语句如下:

select  from test where name in 
(select name from test group by name having COUNT()>1)

结果如图:

基本无法找,列名都不知道,怎么匹配呢?要是有重复的数据怎么筛选呢?
如果实在是要找也行,但是需要时间很长
具体的 *** 作就是:
1、查询数据库表
2、循环根据表查询字段,并拼接sql
拼接sql类似于:
select

from
table
where
column1
like
'%数据%'
or
column2
like
'%数据%'
or
column3
like
'%数据%'
……
3、如果匹配成功,便将表名存入临时表或者表变量中(当然在此之前需要建立临时表或表变量)
4、完成循环后,读取临时表或者表变量,这就是你要找的表
5、如果要进一步筛选字段,则需要下一步动作,循环找到列名,也可以在表循环的时候嵌套循环处理,但是建议不要嵌套循环
字段的寻找和表的寻找类似
sql要写就太多,就不写啦

--dba下的表
SELECT FROM dba_tables;
--当前用户下可以查看的所有表
SELECT FROM all_tables;
--当前用户的表
SELECT FROM user_tables;
SELECT FROM all_Tables WHERE owner = 'user_name大写' AND (table_name LIKE '%XX' OR table_name LIKE 'XX%');
是不是你要的


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/yw/13379641.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-07-25
下一篇 2023-07-25

发表评论

登录后才能评论

评论列表(0条)

保存