总结
子查询为小表时用in,因为此时是子查询驱动主查询
子查询为大表时用exists,因为此时是主查询驱动子查询
order by满足两种情况, 会使用index方式排序
1.order by语句使用索引最左前列
2.使用where子句与order by子句条件列组合满足索引最前列
filesort有2种排序算法
1.双路排序
mysql4.1之前使用双路排序,两次扫描磁盘,最终得到数据
读取行指针和orderby列,对他们进行排序,然后扫描已经排序号的列表,按照列表中的值重新从列表中读取数据
从磁盘读取排序字段,在buffer进行排序,再从磁盘取其他字段
2.单路排序
从磁盘读取查询锁需要的所有列,按照order by在buffer对他们进行排序,然后进行输出
效率高,只需要一次IO,把随机IO变成顺序IO(这里随机IO应该是指单路排序第二次根据排序好的取数据),
但是会使用更多空间,因为他把每一行放到内存。
如果数据列太大,sort_buffer装不下,那就凉了,要进行多次读取,多次排序,还要合并
如果需要排序的列的总大小加上order by列的大小超过了 max_length_for_sort_data定义的字节,mysql就会使用双路排序,当任何需要的列甚至不是用order by的列(text.blob的时候),也会使用双路排序
myisam存储引擎无法使用主键进行排序,会变成filesort,innodb可以
mysql提供的一种日志记录,用来记录在mysql中响应记录超过阈(yu)值的语句
具体指运行时间超过long_query_time值的SQL,则会被记录到慢查询中
//查看是否开启了慢查询,结果是没有
mysql> show variables like '%slow_query_log%';
+---------------------+-----------------------------------------------------------+
| Variable_name | Value |
+---------------------+-----------------------------------------------------------+
| slow_query_log | OFF |
| slow_query_log_file | C:\Program Files\mysql-5.7.17-winx64\data\Calvin-slow.log |
+---------------------+-----------------------------------------------------------+
//开启慢查询,重启后失效,永久生效请修改配置文件
mysql> set global slow_query_log = 1;
//默认大于10秒计入慢查询
mysql> show variables like '%long_query_time%';
+-----------------+-----------+
| Variable_name | Value |
+-----------------+-----------+
| long_query_time | 10.000000 |
+-----------------+-----------+
//更改时间,重新连接才能看到改变
mysql> set global long_query_time=3;
//模拟慢查询
mysql> select sleep(4);
//查看日志
MySQL, Version: 5.7.17 (MySQL Community Server (GPL)). started with:
TCP Port: 3306, Named Pipe: MySQL
Time Id Command Argument
# Time: 2018-08-02T06:13:52.037803Z
# User@Host: root[root] @ localhost [::1] Id: 85
# Query_time: 4.004477 Lock_time: 0.000000 Rows_sent: 1 Rows_examined: 0
use test;
SET timestamp=1533190432;
select sleep(4);
//查看当前系统中有多少条慢查询记录
mysql> show global status like '%Slow_queries%';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Slow_queries | 1 |
+---------------+-------+
//先建个表
mysql> create table dept(
-> id int primary key auto_increment,
-> dename varchar(20) not null default "",
-> deno int);
//开启二进制日志,要不然函数报错
mysql> set global log_bin_trust_function_creators=1;
//定义一个产生随机字符串的函数
//更改结束字符
mysql> delimiter $
mysql> DROP FUNCTION IF EXISTS rand_str;
-> create FUNCTION rand_str(strlen SMALLINT ) RETURNS VARCHAR(255)
-> BEGIN
-> DECLARE randStr VARCHAR(255) DEFAULT 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890';
-> DECLARE i SMALLINT DEFAULT 0;
-> DECLARE resultStr VARCHAR(255) DEFAULT '';
-> WHILE iDO
-> SET resultStr=CONCAT(SUBSTR(randStr,FLOOR(RAND()*LENGTH(randStr))+1,1),resultStr);
-> SET i=i+1;
-> END WHILE;
-> RETURN resultStr;
-> END $
//测试
mysql> select rand_str(10);
+--------------+
| rand_str(10) |
+--------------+
| 6PYirAsQcZ |
+--------------+
//定义一个随机数函数
mysql> create function rand_num() returns int(5)
-> begin
-> declare i int default 0;
-> set i = floor(100 + rand() * 10);
-> return i;
-> end $
//测试
+------------+
| rand_num() |
+------------+
| 103 |
+------------+
//创建一个存储过程
mysql> create procedure insert_emp(in max_num int(10))
-> begin
-> declare i int default 0;
-> set autocommit=0;
-> repeat
-> set i = i + 1;
-> insert into dept(dename, deno) values(rand_str(10), rand_num());
-> until i = max_num
-> end repeat;
-> commit;
-> end $
//调用存储过程
//多来点
mysql> call insert_emp(500000);
Query OK, 0 rows affected (32.30 sec)
//查看profile状态,默认关闭
mysql> show variables like "%profiling%";
+------------------------+-------+
| Variable_name | Value |
+------------------------+-------+
| have_profiling | YES |
| profiling | OFF |
| profiling_history_size | 15 |
+------------------------+-------+
//打开
mysql> set profiling=on;
//查看
mysql> show profiles;
+----------+------------+------------------------------------------------+
| Query_ID | Duration | Query |
+----------+------------+------------------------------------------------+
| 1 | 0.00107075 | show variables like "%profiling%" |
| 2 | 0.00043875 | show tables |
| 3 | 0.00015875 | SELECT DATABASE() |
| 4 | 0.00059625 | show tables |
| 5 | 0.00116725 | select * from tbl_dept |
| 6 | 0.00011975 | SELECT DATABASE() |
| 7 | 0.00025225 | select * from dept limit 1 |
| 8 | 0.00088375 | select * from dept limit 1000 |
| 9 | 0.00740350 | select * from tbl_dept group by id%2 limit 100 |
| 10 | 0.20496625 | select * from dept group by id%2 limit 100 |
+----------+------------+------------------------------------------------+
//进行诊断,查看某条语句的cpu和block io。。看不懂
mysql> show profile cpu,block io for query 10;
+----------------------+----------+----------+------------+--------------+---------------+
| Status | Duration | CPU_user | CPU_system | Block_ops_in | Block_ops_out |
+----------------------+----------+----------+------------+--------------+---------------+
| starting | 0.000063 | 0.000000 | 0.000000 | NULL | NULL |
| checking permissions | 0.000006 | 0.000000 | 0.000000 | NULL | NULL |
| Opening tables | 0.000012 | 0.000000 | 0.000000 | NULL | NULL |
| init | 0.000024 | 0.000000 | 0.000000 | NULL | NULL |
| System lock | 0.000006 | 0.000000 | 0.000000 | NULL | NULL |
| optimizing | 0.000004 | 0.000000 | 0.000000 | NULL | NULL |
| statistics | 0.000024 | 0.000000 | 0.000000 | NULL | NULL |
| preparing | 0.000010 | 0.000000 | 0.000000 | NULL | NULL |
| Creating tmp table | 0.000506 | 0.000000 | 0.000000 | NULL | NULL |
| Sorting result | 0.000009 | 0.000000 | 0.000000 | NULL | NULL |
| executing | 0.000002 | 0.000000 | 0.000000 | NULL | NULL |
| Sending data | 0.204175 | 0.203125 | 0.000000 | NULL | NULL |
| Creating sort index | 0.000040 | 0.000000 | 0.000000 | NULL | NULL |
| end | 0.000002 | 0.000000 | 0.000000 | NULL | NULL |
| query end | 0.000005 | 0.000000 | 0.000000 | NULL | NULL |
| removing tmp table | 0.000005 | 0.000000 | 0.000000 | NULL | NULL |
| query end | 0.000002 | 0.000000 | 0.000000 | NULL | NULL |
| closing tables | 0.000004 | 0.000000 | 0.000000 | NULL | NULL |
| freeing items | 0.000057 | 0.000000 | 0.000000 | NULL | NULL |
| cleaning up | 0.000012 | 0.000000 | 0.000000 | NULL | NULL |
+----------------------+----------+----------+------------+--------------+---------------+