一:基础数据准备

DROP TABLE IF EXISTS `tbl_user`;
CREATE TABLE `tbl_user` (
`id` int() NOT NULL AUTO_INCREMENT,
`username` varchar() DEFAULT NULL,
`email` varchar() DEFAULT NULL,
`age` tinyint() DEFAULT NULL,
`type` int() DEFAULT NULL,
`create_time` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT= DEFAULT CHARSET=utf8; INSERT INTO `tbl_user` VALUES
('', 'admin', 'admin@126.com', '', '', '2018-07-09 11:08:57'),
('', 'mengday', 'mengday@163.com', '', '', '2018-07-09 11:09:00'),
('', 'mengdee', 'mengdee@163.com', '', '', '2018-07-09 11:09:04'),
('', 'root', 'root@163.com', '', '', '2018-07-09 14:36:19'),
('', 'zhangsan', 'zhangsan@126.com', '', '', '2018-07-09 14:37:28'),
('', 'lisi', 'lisi@gmail.com', '', '', '2018-07-09 14:37:31'),
('', 'wangwu', 'wangwu@163.com', '', '', '2018-07-09 14:37:34'),
('', 'zhaoliu', 'zhaoliu@163.com', '', '', '2018-07-11 18:29:24'),
('', 'fengqi', 'fengqi@163.com', '', '', '2018-07-11 18:29:32'); DROP TABLE IF EXISTS `tbl_userinfo`;
CREATE TABLE `tbl_userinfo` (
`id` int() NOT NULL AUTO_INCREMENT,
`address` varchar() DEFAULT NULL,
`user_id` int() DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `idx_userId` (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT= DEFAULT CHARSET=utf8; INSERT INTO `tbl_userinfo` VALUES
('', '上海市', ''),
('', '北京市', ''),
('', '杭州', ''),
('', '深圳', ''),
('', '广州', ''),
('', '海南', '');

二:五百万数据插入

上面插入几条测试数据,在使用索引时还需要插入更多的数据作为测试数据,下面就通过存储过程插入500W条数据作为测试数据

-- 修改mysql默认的结束符号,默认是分号;但是在函数和存储过程中会使用到分号导致解析不正确
DELIMITER $$ -- 随机生成一个指定长度的字符串
CREATE FUNCTION rand_string(n INT) RETURNS VARCHAR()
BEGIN
# 定义三个变量
DECLARE chars_str VARCHAR() DEFAULT 'abcdefghijklmnopqrstuvwxyzABCDEFJHIJKLMNOPQRSTUVWXYZ';
DECLARE return_str VARCHAR() DEFAULT '';
DECLARE i INT DEFAULT ; WHILE i < n DO
SET return_str = CONCAT(return_str, SUBSTRING(chars_str, FLOOR(+RAND()*), ));
SET i = i + ;
END WHILE;
RETURN return_str;
END $$ -- 创建插入的存储过程
CREATE PROCEDURE insert_user(IN START INT(), IN max_num INT())
BEGIN
DECLARE i INT DEFAULT ;
SET autocommit = ;
REPEAT
SET i = i + ;
INSERT INTO tbl_user VALUES ((START+i) ,rand_string(), CONCAT(rand_string(), '@random.com'), +FLOOR(RAND()*), , NOW());
UNTIL i = max_num
END REPEAT;
COMMIT;
END $$ -- 将命令结束符修改回来
DELIMITER ; -- 调用存储过程,插入500万数据,需要等待一会时间,等待执行完成
CALL insert_user(,);
-- Query OK, rows affected ( min 49.89 sec) SELECT COUNT(*) FROM tbl_user;

三:使用索引和不使用索引的比较

使用索引之前的查询

然后给username创建索引再次查询(数据库卡死了,我用sqlyog做)

创建索引用了40秒,属实有点慢

然后再查询试试,基本是秒查了,效率提升很明显

之前再黑窗口加的索引也上去了

然后删除一个索引,byusername

四:explain命令

explain参数详解

查看索引的使用情况:show status like 'Handler_read%'

Handler_read_key: 越高越好
Handler_read_rnd_next:越低越好

查询优化器:

  • 重新定义表的关联顺序(优化器会根据统计信息来决定表的关联顺序)
  • 将外连接转化成内连接(当外连接等于内连接)
  • 使用等价变换规则(如去掉1=1)
  • 优化count()、min()、max()
  • 子查询优化
  • 提前终止查询
  • in条件优化

mysql可以通过 EXPLAIN EXTENDED 和 SHOW WARNINGS 来查看mysql优化器改写后的sql语句

下图提示我们别用*查询,应该写具体那一列

五:走索引的情况和不走索引的情况

1. in走索引

in操作能避免则避免,若实在避免不了,需要仔细评估in后边的集合元素数量,控制在1000个之内。

2. 范围查询走索引

但是条件必须是一个具体的值,如果条件为 now() 当前时间,则会导致全表扫描

3. 模糊查询只有左前缀使用索引

4. 反向条件不走索引 != 、 <> 、 NOT IN、IS NOT NULL

一个优化的实例:

# 常见的对not in的优化,使用左连接加上is null的条件过滤
SELECT id, username, age FROM tbl_user WHERE id NOT IN (SELECT user_id FROM tbl_order); SELECT u.id, u.username, u.age
FROM tbl_user u
LEFT JOIN tbl_order o ON u.id = o.user_id
WHERE o.user_id IS NULL;

5. 对条件计算(使用函数或者算数表达式)不走索引

使用函数计算不走索引,无论是对字段使用了函数还是值使用了函数都不走索引,解决办法通过应用程序计算好,将计算的结果传递给sql,而不是让数据库去计算

6. 查询时必须使用正确的数据类型

如果索引字段是字符串类型,那么查询条件的值必须使用引号,否则不走索引

7. or 使用索引和不使用索引的情况

or 只有两边都有索引才走索引,如果都没有或者只有一个是不走索引的

8. 用union少用or

尽量避免使用or,因为大部分or连接的两个条件同时都进行索引的情况几率比较小,应使用uninon代替,这样能走索引的走索引,不能走索引的就全表扫描。

9. 能用union all就不用union

union all 不去重复,union去重复,union使用了临时表,应尽量避免使用临时表

10. 复合索引

对于复合索引,如果单独使用右边的索引字段作为条件时不走索引的。即复合索引如果不满足最左原则leftmost不会走复合索引

暂未完成,更新还会继续

MYSQL调优实战的更多相关文章

  1. 数据库MySQL调优实战经验总结<转>

    数据库MySQL调优实战经验总结 MySQL 数据库的使用是非常的广泛,稳定性和安全性也非常好,经历了无数大小公司的验证.仅能够安装使用是远远不够的,MySQL 在使用中需要进行不断的调整参数或优化设 ...

  2. 数据库MySQL调优实战经验总结

    MySQL 数据库的使用是非常的广泛,稳定性和安全性也非常好,经历了无数大小公司的验证.仅能够安装使用是远远不够的,MySQL 在使用中需要进行不断的调整参数或优化设置,才能够发挥 MySQL 的最大 ...

  3. Java虚拟机性能监控与调优实战

    From:  https://c.m.163.com/news/a/D7B0C6Q40511PFUO.html?spss=newsapp&fromhistory=1 Java虚拟机性能监控与调 ...

  4. MySQL 调优/优化的 100 个建议

    MySQL 调优/优化的 100 个建议   MySQL是一个强大的开源数据库.随着MySQL上的应用越来越多,MySQL逐渐遇到了瓶颈.这里提供 101 条优化 MySQL 的建议.有些技巧适合特定 ...

  5. MySQL 调优基础(一) CPU与进程

    一般而言,MySQL 的调优可以分为两个层面,一个是在MySQL层面上进行的调优,比如SQL改写,索引的添加,MySQL各种参数的配置:另一个层面是从操作系统的层面和硬件的层面来进行调优.操作系统的层 ...

  6. MySQL调优系列基础篇

    前言 有一段时间没有写博客了,整天都在忙,上班,录制课程,恰巧最近一段时间比较清闲,打算弄弄MYSQL数据库. 关于MySQL数据库,这里就不做过多的介绍,开源.免费等特性深受各个互联网行业喜爱,尤其 ...

  7. JVM 性能调优实战之:一次系统性能瓶颈的寻找过程

    玩过性能优化的朋友都清楚,性能优化的关键并不在于怎么进行优化,而在于怎么找到当前系统的性能瓶颈.性能优化分为好几个层次,比如系统层次.算法层次.代码层次…JVM 的性能优化被认为是底层优化,门槛较高, ...

  8. JVM 性能调优实战之:使用阿里开源工具 TProfiler 在海量业务代码中精确定位性能代码

    本文是<JVM 性能调优实战之:一次系统性能瓶颈的寻找过程> 的后续篇,该篇介绍了如何使用 JDK 自身提供的工具进行 JVM 调优将 TPS 由 2.5 提升到 20 (提升了 7 倍) ...

  9. mysql调优 基础

    MySQL调优可以从几个方面来做: 1. 架构层:做从库,实现读写分离: 2.系统层次:增加内存:给磁盘做raid0或者raid5以增加磁盘的读写速度:可以重新挂载磁盘,并加上noatime参数,这样 ...

随机推荐

  1. hdu 6201 【树形dp||SPFA最长路】

    http://acm.hdu.edu.cn/showproblem.php?pid=6201 n个城市都在卖一种书,该书的价格在i城市为cost[i],商人打算从某个城市出发到另一个城市结束,途中可以 ...

  2. js+canvas黑白棋

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  3. CF1238E.Keyboard Purchase 题解 状压/子集划分DP

    作者:zifeiy 标签:状压DP,子集划分DP 题目链接:https://codeforces.com/contest/1238/problem/E 题目大意: 给你一个长度为 \(n(n \le ...

  4. oracle函数 NEW_TIME(dt1,c1,c2)

    [功能]:给出时间dt1在c1时区对应c2时区的日期和时间 [参数]:dt1,d2 日期型 [返回]:日期时间 [参数]:c1,c2对应的 时区及其简写 大西洋标准时间:AST或ADT 阿拉斯加_夏威 ...

  5. 威胁快报|挖矿团伙8220进化,rootkit挖矿趋势兴起

    近日,阿里云安全团队发现8220挖矿团伙为了更持久的驻留主机以获得最大收益,开始使用rootkit技术来进行自我隐藏.这类隐藏技术的使用在watchdogs等挖矿蠕虫使用后开始出现逐渐扩散和进化的趋势 ...

  6. IntelliJ IDEA和Eclipse设置JVM运行参数

    打开 IDEA 安装目录,看到有一个 bin 目录,其中有两个 vmoptions 文件,需针对不同的JDK进行配置: 32 位:idea.exe.vmoptions64 位:idea64.exe.v ...

  7. laravel5.4 发送SMTP邮件

    https://blog.csdn.net/qq_35843527/article/details/77880631 Lumen / Laravel 5.4 使用网易邮箱 SMTP 发送邮件 获取网易 ...

  8. css设置Overflow实现隐藏滚动条的同时又可以滚动

    .scroll-list ul{ white-space: nowrap; -webkit-overflow-scrolling: touch; overflow-x: auto; overflow- ...

  9. H3C 帧中继数据链路标识

  10. Java中方法的格式

    [修饰符] 返回值类型 方法名([参数类型 形式参数1,参数类型 形式参数2,……]) {             执行语句;     [return 返回值;]//需要的话 } 参数列表(参数的类型 ...