慕课网视频学习笔记
1、SQL及索引
2、数据库表结构
3、系统配置
4、硬件
示例数据库下载地址:http://downloads.mysql.com/docs/sakila-db.zip
安装教学地址:https://dev.mysql.com/doc/sakila/en/sakila-installation.html
注意:window下cmd安装 \ 全部替换成 / 才可以成功
使用mysql慢查日志对有效率问题的sql进行监控
#1、查看mysql是否开启慢查询日志
show variables like 'slow_query_log';
#2、设置没有索引的记录到慢查询日志
set global log_queries_not_using_indexes=on;
#3、查看超过多长时间的sql进行记录到慢查询日志
show variables like 'long_query_time';
#4、开启慢查询日志
set global slow_query_log=on;
#5、设置超过多少秒以后的查询插入慢查日志中
set global long_query_time=1;
#6、查看日志记录位置
show variables like 'slow%';
#7、查看日志(退出mysql环境)
tail -50 D:\newphpStudy\MySQL\data\BlueSummer-PC-slow.log;
pt-query-digest
安装过程:
[root@localhost ~]# wget percona.com/get/pt-query-digest
[root@localhost ~]# chmod u+x pt-query-digest
[root@localhost ~]# mv /root/pt-query-digest /usr/bin/
输出到文件:pt-query-digest slow-log > slow_log.report
输出到数据库表: pt-query-digest slow.log -review \
1、查询次数多且每次查询占用时间长的SQL(通常为pt-query-digest分析的前几个查询)
2、IO大的SQL(注意pt-query-digest分析中的Rows examine项)
3、未命中索引的SQL(注意pt-query-digest分析中的Rows examine和Rows Send的对比)
explain select customer_id,first_name,last_name from customer;
explain返回各列的含义:
Using filesort:看到这个的时候,查询就需要优化了。MYSQL需要进行额外的步骤来发现如何对返回的行排序。它根据连接类型以及存储排序键值和匹配条件的全部行的行指针来排序全部行。
Using temporary:看到这个的时候,查询需要优化了。这里,MYSQL需要创建一个临时表来存储接口,这通常发生在对不同的列表进行ORDER BY上,而不是GROUP BY上。
max()优化:建立覆盖索引
优化前:
建立索引:
create index inx_paydate on payment(payment_date);
优化后:
count()优化:使用OR NULL
-- 在一条SQL中同时查出2006和2007年电影的数量-优化count()函数
SELECT COUNT(release_year='2006' OR NULL) AS '2006年电影数量',
COUNT(release_year='2007' OR NULL) AS '2007年电影数量'
FROM film;
通常情况下,需要把子查询优化为join查询,但在优化时需要注意关联键是否有一对多的关系,因为此时要注意会有重复数据。(join查询不需要内建临时表)
distinct --去除重复值
优化前:
SELECT actor.first_name,actor.last_name,COUNT(*)
FROM sakila.film_actor
INNER JOIN film_actor USING(actor_id)
GROUP BY film_actor.actor_id;
优化后:
SELECT actor.first_name,actor.last_name,c
FROM sakila.actor INNER JOIN(
SELECT actor_id,COUNT(*) AS cnt FROM sakila.film_actor GROUP BY
actor_id
)AS c USING(actor_id);
limit常用于分页处理,时常会伴随order by从句使用,因此大多时候会使用Filesorts,这样造成大量的IO问题。
SELECT film_id,description FROM sakila.film ORDER BY title LIMIT 50,5;
优化LImie查询:
优化步骤1:使用有索引的列或主键进行order by操作
SELECT film_id, descripytion FROM sakila.film ORDER BY film_id LIMIT 50,5;
优化步骤2:记录上次返回的主键,在下次查询时使用主键过滤(避免了数据量大时扫描过多的记录)
SELECT film_id, description FROM sakila.film WHERE film_id > 55 and film_id <= 60 ORDER BY film_id LIMIT 1,5;
-- 如果不是连续的,可以自己建一列保证其值顺序递增也可以。
*避免数据量大时扫描过多的记录
使用主键或索引来order by是可以减少扫描列:
在表中建立索引,然后在索引中找到符合查询条件的索引值,最后通过保存在ROWID(相对于页码)快速找到表中对应的记录。索引的建立时表中比较有指向性的字段,相对于目录,比如说行政区域代码,同一个地域的行政区域代码都是相同的,那么给这一列加上索引,避免让它重复扫描,从而达到优化的目的。