1. 查询SQL尽量不使用 select *,而是 select 具体字段

正确使用

SELECT id, name FROM student;

反例: SELECT * FROM student;

  • 只取需要的字段,节省资源
  • select * 进行查询时,很可能不会使用到覆盖索引,造成回表查询

2. 如果知道查询结果只有一条,或者只要最大/最小一条,建议用 limit 1

正确使用

SELECT id, name FROM student WHERE name = '张三' limit 1;

反例: SELECT id, name FROM student WHERE name = ‘张三’;

  • 加上 limit 1 之后,只要找到了对应的一条记录,就不会继续向下扫描,提高了效率
  • 如果 name 为唯一索引的话,可以不加 limit 1

3. 尽量避免在 where 子句中使用 or 来连接条件,使用 union all

正确使用

# 查询 id 为 1,或者 age 为 18 岁的用户
SELECT id, name, age FROM student WHERE id = 1
UNION ALL
SELECT id, name, age FROM student WHERE age = 18;

反例:SELECT id, name, age FROM student WHERE id = 1 OR age = 18;

  • 使用 or 可能会使索引失效,从而全表扫描

4. 优化 limit 分页,使用 order by + 索引

正确使用

SELECT id, name FROM student ORDER BY id LIMIT 10000, 10;

反例:SELECT id, name FROM student LIMIT 10000, 10;

  • 当偏移量很大的时候,查询效率就会很低。

    因为MySQL并非是跳过偏移量直接去取后面的数据,而是先把偏移量 加上 要取的条数,然后再把前面偏移量这一段的数据抛弃掉再返回。

5. 优化 like 语句,尽量不要 前模糊

正确使用

SELECT id, name FROM student WHERE name like '张%';

反例:SELECT id, name FROM student WHERE name like ‘%张’;

  • 将 % 放到前面,并不走索引

6. 使用 where 条件限定要查询的数据,避免返回多余的行

正确使用

# 查询某个学生是否为VIP
SELECT id, name FROM student WHERE id = '1' and isVip = '1';

反例:SELECT id, name FROM student WHERE isVip = ‘1’; 再判断查出的结果中,id 是否包含 1

  • 需要什么数据,就查什么数据,避免返回多余的数据

7. 尽量避免在索引上使用 mysql 的内置函数

正确使用

# 查询最近七天内登陆过的用户(假设loginTime加了索引)
SELECT id, loginTime FROM student WHERE loginTime >= DATE_ADD(NOW(), INTERVAL -7 DAY)

反例:SELECT id, loginTime FROM student WHERE DATE_ADD(loginTime, INTERVAL 7 DAY) >= now();

  • 索引列上使用 MySQL 的内置函数,索引失效

8. 尽量避免在 where 子句中对字段进行表达式操作

正确使用

SELECT id, name FROM student WHERE age = 18;

反例:SELECT id, name FROM student WHERE age - 1 = 10;

  • 对加了索引的字段进行运算,会让索引失效,进行全表扫描

9. inner join、left join、right join,优先使用inner join,如果使用left join,左边表结果集尽量小

  • inner join:内连接,在两张表进行连接查询时,只保留两张表中完全匹配的结果集
  • left join:在两张表进行连接查询时,会返回左表所有的行,即使在右表中没有匹配的记录
  • right join:在两张表进行连接查询时,会返回右表所有的行,即使在左表中没有匹配的记录

正确使用

SELECT s.* FROM (SELECT * FROM student WHERE id > 2) s
LEFT JOIN teacher t ON s.id = t.teachId;

反例:SELECT s.* FROM student s LEFT JOIN teacher t ON s.id = t.teachId WHERE s.id > 2;

10. 尽量避免在 where 子句中使用 != 或 <> 操作符

正确使用

SELECT id, name FROM student WHERE age > 18;
SELECT id, name FROM student WHERE age < 18;

反例:SELECT id, name FROM student WHERE age <> 18;

  • 使用 != 和 <> 很可能会让索引失效

11. 使用联合索引时,注意索引列的顺序,一般遵循最左匹配原则

表结构:(有一个联合索引 idx_userid_age,userId在前,age在后)

CREATE TABLE `user`(`id` int (11) NOT NULL AUTO_INCREMENT,`userId` int(11) NOT NULL,`age` int (11) DEFAULT NULL,`name` varchar (255) NOT NULL,PRIMARY KEY (`id`),KEY `idx_userid_age` (`userId`,`age`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

正确使用

SELECT id, name FROM student WHERE userId = 1 and age = 18;

反例:SELECT id, name FROM student WHERE age = 18;

  • 当我们创建了一个 联合索引 的时候,如(k1, k2, k3),相当于创建了(k1)、(k1、k2)和(k1、k2、k3)三个索引,这就是最左匹配原则
  • 联合索引不满足最左原则,索引一般会失效,但是这个还跟Mysql优化器有关的

12. 对查询进行优化,应考虑在 where 及 order by涉及的列上建立索引,尽量避免全表扫描

正确使用

# 添加索引
ALTER TABLE student ADD INDEX idx_address_age ( address, age );SELECT id, name FROM student WHERE address = '山东' ORDER BY age;

反例:SELECT id, name FROM student WHERE address = ‘山东’ ORDER BY age; 直接使用

13. 如果插入数据过多,使用批量插入

<foreach>

14. 在适当的时候,使用覆盖索引

覆盖索引能够使 SQL语句 不需要回表,仅仅访问索引就能够得到所有需要的数据

15. 慎用 distinct 关键字

带 distinct 的语句cpu时间和占用时间都高于不带distinct的语句。

因为当查询很多字段时,如果使用distinct,数据库引擎就会对数据进行比较,过滤掉重复数据,然而这个比较、过滤的过程会占用系统资源,cpu时间。

16. 删除冗余和重复索引

比如一个索引为 KEY idx_userId (userId) ,另一个为 KEY idx_userid_age (userId, age),那么就可以删除单独的 userId 索引

17. 如果数据量较大,优化修改、删除语句

可以分批次操作,如果一次性操作太多数据,可能会有lock wait timeout exceed的错误,所以建议分批操作。

18. where 子句中考虑使用 默认值 代替null

设计表时,可以给字段设置默认值(例如,设置 age的默认值为 0)

正确使用

SELECT * FROM student WHERE age > 0;

反例:SELECT * FROM student WHERE age IS NOT NULL;

19. 不要有超过 5 个以上的表连接

如果一定需要连接很多表才能得到数据,那么意味着糟糕的设计了。

20. exist & in的合理使用

正确使用

# 查询某企业所有部门的所有员工
SELECT * FROM employee e EXISTS (SELECT 1 FROM department  d WHERE e.deptId = d.id);

反例:SELECT * FROM employee WHERE deptId IN (SELECT id FROM department);

  • exists查询先执行主查询,获得数据后(一次连接),再放到子查询中做条件验证(一次连接),根据验证结果(true或者false),来决定主查询的数据结果是否保留。
  • 如果使用 in :需要先查询部门表(一次连接),再由得到的部门id 查询员工表(N次连接)

21. 尽量用 union all 替代 union

如果检索结果中不会有重复的记录,推荐union all 替换 union。

  • 如果使用 union,不管检索结果有没有重复,都会尝试进行合并,然后在输出最终结果前,进行排序

22. 索引不宜太多,一般 5 个以内

索引并不是越多越好,索引虽然提高了查询的效率,但是也降低了插入和更新的效率

23. 尽量使用数字型字段,若只含数值信息的字段尽量不要设计为字符型

相对于数字型字段,字符型会降低查询和连接的性能,并会增加存储开销。

24. 索引不适合建在有大量重复数据的字段上,如性别

因为SQL优化器是根据表中数据量来进行查询优化的,如果索引列有大量重复数据,Mysql查询优化器推算发现不走索引的成本更低,很可能就放弃索引了。

25. 尽量避免向客户端返回过多数据量

正确使用

# 查询最近一年注册的学生信息
SELECT * FROM student WHERE create_time >= DATE_SUB(NOW(), INTERVAL 1 Y) LIMIT 0, 200;
# 例如先显示200条,往后翻的时候再重新获取

反例:SELECT * FROM student WHERE create_time >= DATE_SUB(NOW(), INTERVAL 1 Y);

26. 当在 SQL语句中连接多个表时,使用表的别名

27. 尽可能使用 varchar / nvarchar 代替 char / nchar

28. 为了提高 group by 语句的效率,可以在执行到该语句前,使用 having 把不需要的记录过滤掉。

正确使用

SELECT sex, AVG(age) FROM student
GROUP BY sex HAVING sex = '男';

反例:SELECT sex, AVG(age) FROM student GROUP BY sex;

29. 如果字符类型是字符串,where 时一定要用 引号 括起来,否则索引失效

正确使用

SELECT id, name FROM student WHERE phone = '12345';

反例:SELECT id, name FROM student WHERE phone = 12345;

  • 因为不加单引号时,是字符串跟数字的比较,它们类型不匹配,MySQL会做隐式的类型转换,把它们转换为浮点数再做比较。

【MySQL】 # 优化你的SQL语句相关推荐

  1. MySQL优化之三:SQL语句优化

    一 SQL语句优化的一般步骤: 1 通过show status命令了解各种SQL语句的执行频率 mysql> show status;                #show status:显 ...

  2. mysql 执行效率命令_MySQL优化--explain 分析sql语句执行效率

    MySQL优化--explain 分析sql语句执行效率 explain 命令 explain 命令在解决数据库性能上市第一推荐使用命令,大部分的性能问题可以通过此命令来简单解决,explain可以用 ...

  3. mysql sql优化_MySQL数据库SQL语句优化原理专题(三)

    需求 做过开发的同学,对分页肯定不会陌生,因为很多前台页面展示,为了更好的展示数据,就会用到分页,所以如何写一个高性能的分页SQL语句,是每一个开发人员需要掌握的技能. 分页SQL 这里给大家写一个分 ...

  4. mysql 如何优化sql语句,如何优化SQL?MySQL中超实用的SQL语句送给大家

    如何优化SQL?MySQL中超实用的SQL语句送给大家 如何优化SQL?MySQL中超实用的SQL语句送给大家 在写SQL时,经常灵活运用一些SQL语句编写的技巧,可以大大简化程序逻辑.减少程序与数据 ...

  5. sql查询索引语句_sql优化总结--基于sql语句优化和索引优化

    概述 最近做查询,统计和汇总.由于数据量比较庞大,大部分表数据上百万,甚至有的表数据上千万.所以在系统中做sql优化比较多,特此写一篇文章总结一下关于sql优化方面的经验. 导致查询缓慢的原因 1.数 ...

  6. 软件创新实验室:MySQL数据库与简单SQL语句使用

    文章目录 前言 简介 特点 SQL DDL:操作数据库.表 DML:增删改表中数据 DQL:查询表中的记录 后记 拓展 范式 第一范式 1NF 第二范式 2NF 第三范式 3NF B+树 节点结构 插 ...

  7. mysql创建用户表的sql语句,mysql创建表的sql语句

    mysql 动态sql语句,如何用一款小工具大大加速MySQL SQL语句优化(附源,mysql分页查询sql语句,mysql创建表的sql语句 mysql建表语句_计算机软件及应用_IT/计算机_专 ...

  8. MySQL数据库https接口_第三章 mysql 数据库接口程序以及SQL语句操作

    mysql  数据库接口程序以及SQL语句操作 用于管理数据库: 命令接口自带命令 DDL:数据定义语言(create drop ) DCL: 数据控制语言(grant revoke) DML: 数据 ...

  9. mysql优化说出九条_技术分享 | MySQL 优化:为什么 SQL 走索引还那么慢?

    原标题:技术分享 | MySQL 优化:为什么 SQL 走索引还那么慢? 背景 2019-01-11 9:00-10:00 一个 MySQL 数据库把 CPU 打满了. 硬件配置:256G 内存,48 ...

  10. mysql 语句_如何记录MySQL执行过的SQL语句

    很多时候,我们需要知道 MySQL 执行过哪些 SQL 语句,比如 MySQL 被注入后,需要知道造成什么伤害等等.只要有 SQL 语句的记录,就能知道情况并作出对策.服务器是可以开启 MySQL 的 ...

最新文章

  1. Promise和Promise的方法
  2. 【Java】多线程编程(并发编程)基础(上)
  3. BZOJ4066: 简单题
  4. 第二轮“双一流”名单:这 44 所高校有调整!
  5. android listview中item通过viewpager实现
  6. iOS开发笔记--Layer 图层圆角、边框 、底纹其他常用操作
  7. 1054. The Dominant Color (20)
  8. 关于使用.net页面刷新时的问题下拉列表框值改变时,页面动态刷新
  9. 32位应用程序如何使用大于2GB的内存?
  10. Flex一个RemoteObject调用JAVA对象里面的多个方法
  11. 移动办公——千脑云电脑 在线存储,中国人的在线办公室
  12. 详解怎么申请注册一个自己的电子邮箱邮件?怎么注册邮箱账号?
  13. 侯捷C++八部曲笔记(三、设计模式)
  14. Android 集成腾讯Bugly
  15. 触摸屏:Linux输入子系统:多点触控协议
  16. 湖北武汉施工员报考施工员安全意识的建立方法建筑七大员报考
  17. 用surfaceview播放FFmpeg解码视屏
  18. 微信小程序 - [完整源码] 全屏左右菜单联动效果,左侧分类与右侧内容联动,类似美团饿了么的点餐页面 “左边菜单,右边内容“ 效果(开箱即用的示例源码,代码干净整洁且注释详细)
  19. 永久关闭Linux防火墙
  20. 学习笔记:在Ubuntu16.04系统内安装Petalinux软件(包括如何安装Ubuntu16.04和相关支持库 详解)

热门文章

  1. unity,通俗解释什么是协程
  2. Python语言基础编程
  3. 需求调研(一)——调研流程和时间的把握
  4. HihoCoder——Trie树
  5. Mac下配置VIM .vimrc
  6. css中多行文本溢出显示省略号的方法
  7. 二叉树后序遍历非递归算法(详解)
  8. python3 打印目录下所有模块_使用 Python 函数进行模块化
  9. STM32进入低功耗模式以及唤醒(RTC+中断)
  10. Nomad 服务编排