本文目录一览:
- Mysql学会查看sql的执行计划
- 如何查看mysql执行过的语句
- 如何记录MySQL执行过的SQL语句
- 如何查看mysql中执行sql语句
- mysql中怎样显示服务器正在执行的sql任务
- 如何看mysql执行的sql语句
Mysql学会查看sql的执行计划
首先在Mysql的服务中有连接器、查询缓存(Mysql8 已经删除)、分析器、优化器、执行器等,所有跨存储引擎的功能都在这一层实现。
而一条sql怎么执行是由优化器决定的。优化器是在表里面有多个索引的时候,决定使用哪个索引;或者在一个语句有多表关联(join)的时候,决定各个表的连接顺序。
而执行计划就是优化器优化后的sql的执行的详细方案。
Mysql中查看执行计划的方式有两种:1. 使用desc
,2. 使用explain
。使用它俩的效果是一样的。
接下来要通过执行计划知道sql是怎么执行的。
执行计划中有几个重要的字段,分别是:
id
table
type
possible_keys
key
key_len
Extra
id
可以通过ID来查看在多表联查中sql是先查询哪张表的。id相同的从上往下依次执行,id不同的id大的先执行。
table
table当然就是查询的表名。
type
查询的类型分为:ALL
、index
、range
、ref
、eq_ref
、const(system)
、null
。
- ALL:指的是全盘扫描,没有走任何索引。查询结果集大于25% 优化器可能会走全盘扫描。字符串查询的时候一定要加
""
,不然可能会全索引扫描(隐式转换)。统计信息失效或者过旧也可能走全盘扫描,因为优化器会参考统计信息来制定执行计划。 - index:全索引扫描,就是扫描整颗索引树。
- range:索引范围,查询索引树的一部分范围。范围索引中,
=
、like
的效率会比or
、in
的效率高。使用like %
前面的不走索引。 - ref:辅助索引的等值查询。
- eq_ref:多表连接查询中,被连接的表的连接条件列是主键或者唯一键。
- const(system):主键或者唯一键的等值查询。
- null:没有数据。
它们的性能是依次递增的,全盘扫描性能最差,
const
性能最高。
possible_keys
查询过程中可能用到的索引。
key
真正使用到的索引。
key_len
走索引的长度。
key_len 的计算方法:
int
类型最长存储4个字节长度的数字。有not null
是4字节,没有的话会花1字节存储是否为null
。tinyint
最大存储一个字节,也会花1字节来判断是否为null
。- 字符串类型:字符集
utf8mb4
为1-4字节。 varchar
超过255会预留2个字节存储长度,没超过预留1个字节。key_len
永远是你设置的长度的最大值。 联合索引可以通过key_len
来判断走了几个索引。 使用desc format=json select * from table
可以查看详细情况。
filtered
索引扫描过滤掉数据的占比。
Extra
额外的信息:
- Using filesort:MySQL对数据在sql层进行了排序,而不是按照表内的索引进行排序读取。效率比较低。
- Using temporary:使用临时表保存中间结果,也就是说 MySQL 在对查询结果排序时使用了临时表,常见于
order by
或group by
。 - Using index:表示 SQL 操作中使用了覆盖索引(Covering Index),避免了访问表的数据行,效率高。
- Using index condition:表示 SQL 操作命中了索引,但不是所有的列数据都在索引树上,还需要访问实际的行记录。
- Using where:表示 SQL 操作使用了 where 过滤条件。
- Select tables optimized away:基于索引优化
MIN/MAX
操作或者MyISAM
存储引擎优化COUNT(*)
操作,不必等到执行阶段再进行计算,查询执行计划生成的阶段即可完成优化。 - Using join buffer (Block Nested Loop):表示 SQL 操作使用了关联查询或者子查询,且需要进行嵌套循环计算。
如何查看mysql执行过的语句
开启记录MySQL执行过SQL语句的方法很简单:编辑/etc/my.cnf
文件,在[mysqld]
节下面添加:
log=/var/lib/mysql/sql_row.log
日志的路径可以根据需要定义。 修改后的配置示例:
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
user=mysql
# Default to using old password format for compatibility with mysql 3.x
# clients (those using the mysqlclient10 compatibility package).
old_passwords=1
log=/var/lib/mysql/sql_row.log
# Disabling symbolic-links is recommended to prevent assorted security risks;
# to do so, uncomment this line:
# symbolic-links=0
[mysqld_safe]
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
修改完毕后,记得重启 MySQL:
service mysql restart
# 或者
/etc/init.d/mysqld stop
/etc/init.d/mysqld start
现在你去 /var/lib/mysql/
路径下的 sql_row.log
文件应该是能够看到 MySQL 什么时候执行了哪些程序了。
如何记录MySQL执行过的SQL语句
第一种:查 Slow query 的 SQL 语法
log_slow_queries = /var/log/mysql/mysql-slow.log
long_query_time = 2
超过2秒的SQL语法记录起来,设短一点来记录除错也是一种方法。
第二种:设 MySQL Replication 用 binlog
log_bin = /var/log/mysql/mysql-bin.log
此档要用 mysqlbinlog
解来看。MySQL 会将所有 INSERT/UPDATE/DELETE
语法记录于此(但是语法可能跟你想的不同),这是要写给 SLAVE 用的 log 档。
第三种:推荐此方法,将 MySQL 执行的每行指令全都记录起来
log = /tmp/mysql.log
重启 MySQL 后,使用 tail -f /tmp/mysql.log
就可以看到。
补充
最早前的方法是 mysqldump
,然后执行完后再 mysqldump
,再 diff
,但是在 DB 1G 后就放弃此方法了。
如何查看mysql中执行sql语句
如果我的理解没错的话,你的意思是正在执行的sql语句吧。 命令:
SHOW FULL PROCESSLIST;
示例:
SELECT SLEEP(20);
另一个session执行:
SHOW FULL PROCESSLIST;
可以看到正在执行的语句:
| 183 | root | localhost | NULL | Query | 6 | User sleep | SELECT SLEEP(20) |
mysql中怎样显示服务器正在执行的sql任务
查询Oracle正在执行的sql语句及执行该语句的用户
SELECT b.sid oracleID,
b.username 登录Oracle用户名,
b.serial#,
spid 操作系统ID,
paddr,
sql_text 正在执行的SQL,
b.machine 计算机名
FROM v$process a,
v$session b,
v$sqlarea c
WHERE a.addr = b.paddr
AND b.sql_hash_value = c.hash_value;
查看正在执行sql的发起者的发放程序
SELECT OSUSER 电脑登录身份,
PROGRAM 发起请求的程序,
USERNAME 登录系统的用户名,
SCHEMANAME,
B.Cpu_Time 花费cpu的时间,
STATUS,
B.SQL_TEXT 执行的sql
FROM V$SESSION A
LEFT JOIN V$SQL B ON A.SQL_ADDRESS = B.ADDRESS
AND A.SQL_HASH_VALUE = B.HASH_VALUE
ORDER BY b.cpu_time DESC;
查出oracle当前的被锁对象
SELECT l.session_id sid,
s.serial#,
l.locked_mode 锁模式,
l.oracle_username 登录用户,
l.os_user_name 登录机器用户名,
s.machine 机器名,
s.terminal 终端用户名,
o.object_name 被锁对象名,
s.logon_time 登录数据库时间
FROM v$locked_object l,
all_objects o,
v$session s
WHERE l.object_id = o.object_id
AND l.session_id = s.sid
ORDER BY sid, s.serial#;
kill掉当前的锁对象可以为
ALTER SYSTEM KILL SESSION 'sid, s.serial#';
如何看mysql执行的sql语句
1. 先通过status命令查看Mysql运行状态
STATUS;
输出示例:
--------------
mysql Ver 14.14 Distrib 5.1.73, for redhat-linux-gnu (x86_64) using readline 5.1
Connection id: 113752
Current database: information_schema
Current user: push_user@localhost
SSL: Not in use
Current pager: stdout
Using outfile: ''
Using delimiter: ;
Server version: 5.1.73 Source distribution
Protocol version: 10
Connection: Localhost via UNIX socket
Server characterset: latin1
Db characterset: utf8
Client characterset: latin1
Conn. characterset: latin1
UNIX socket: /tmp/mysql.sock
Uptime: 22 days 8 hours 31 min 23 sec
Threads: 38 Questions: 1037751897 Slow queries: 2356 Opens: 79836
Flush tables: 1 Open tables: 64 Queries per second avg: 537.282
--------------
在上面显示列表的最后一条,我们来查看Slow queries
这一项的值,如果多次查看的值大于0的话,说明有些查询sql命令执行时间过长。
2. 这时再通过show processlist命令来查看当前正在运行的SQL,从中找出运行慢的SQL语句,找到执行慢的语句后,再用explain命令查看这些语句的执行计划。
SHOW PROCESSLIST;
输出示例:
+--------+-----------+---------------------+--------------------+---------+-------+-------+------------------+
| Id | User | Host | db | Command | Time | State | Info |
+--------+-----------+---------------------+--------------------+---------+-------+-------+------------------+
| 50270 | ambari | DataBase-01:41512 | ambari | Sleep | 23 | | NULL |
| 50271 | ambari | DataBase-01:41511 | ambari | Sleep | 6 | | NULL |
| 50272 | ambari | DataBase-01:41514 | ambari | Sleep | 23 | | NULL |
| 62452 | oozie | DataBase-02:42987 | oozie | Sleep | 25 | | NULL |
| 63660 | ambari | DataBase-01:56052 | ambari | Sleep | 0 | | NULL |
| 110404 | push_user | localhost:33817 | quartz | Sleep | 12 | | NULL |
| 112835 | push_user | localhost:46571 | hibernate | Sleep | 1 | | NULL |
| 113752 | push_user | localhost | information_schema | Query | 0 | | show processlist |
+--------+-----------+---------------------+--------------------+---------+-------+-------+------------------+
或者通过如下命令查询:
USE information_schema;
SELECT * FROM PROCESSLIST WHERE info IS NOT NULL;
输出示例:
+--------+-----------+-----------+--------------------+---------+------+-----------+--------------------------------------------------+
| ID | USER | HOST | DB | COMMAND | TIME | STATE | INFO |
+--------+-----------+-----------+--------------------+---------+------+-----------+--------------------------------------------------+
| 113752 | push_user | localhost | information_schema | Query | 0 | executing | SELECT * FROM PROCESSLIST WHERE info IS NOT NULL |
+--------+-----------+-----------+--------------------+---------+------+-----------+--------------------------------------------------+