工作实战: 让 SQL 飞起来

1 使用高效的查询

SET FOREIGN_KEY_CHECKS=0;-- ----------------------------
-- Table structure for class_a
-- ----------------------------
DROP TABLE IF EXISTS `class_a`;
CREATE TABLE `class_a` (`name` varchar(16) NOT NULL,`age` int(11) DEFAULT NULL,`city` varchar(16) NOT NULL,PRIMARY KEY (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;-- ----------------------------
-- Records of class_a
-- ----------------------------
INSERT INTO `class_a` VALUES ('伯杰', '21', '千叶');
INSERT INTO `class_a` VALUES ('布朗', '22', '东京');
INSERT INTO `class_a` VALUES ('拉里', '19', '埼玉');
/*
Navicat MySQL Data Transfer
Target Server Type    : MYSQL
Target Server Version : 50723
File Encoding         : 65001Date: 2019-03-24 18:47:42
*/SET FOREIGN_KEY_CHECKS=0;-- ----------------------------
-- Table structure for class_b
-- ----------------------------
DROP TABLE IF EXISTS `class_b`;
CREATE TABLE `class_b` (`name` varchar(16) NOT NULL,`age` int(11) DEFAULT NULL,`city` varchar(16) NOT NULL,PRIMARY KEY (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;-- ----------------------------
-- Records of class_b
-- ----------------------------
INSERT INTO `class_b` VALUES ('和泉', '18', '千叶');
INSERT INTO `class_b` VALUES ('武田', '20', '千叶');
INSERT INTO `class_b` VALUES ('石川', '19', '神奈川');

使用 EXISTS 时更快的原因有以下两个。
●  如果连接列(id)上建立了索引,那么查询 Class_B 时不用查实
际的表,只需查索引就可以了。
●  如果使用 EXISTS,那么只要查到一行数据满足条件就会终止查询,
不用像使用 IN 时一样扫描全表。在这一点上 NOT EXISTS 也一样。

当 IN 的参数是子查询时,数据库首先会执行子查询,然后将结果存储在一张临时的工作表里(内联视图),然后扫描整个视图。很多情况下这种做法都非常耗费资源。使用 EXISTS 的话,数据库不会生成临时的工作表。但是从代码的可读性上来看, IN 要比 EXISTS 好。使用 IN 时的代码看起来更加一目了然,易于理解。因此,如果确信使用 IN 也能快速获取结果,就没有必要非得改成 EXISTS 了。而且,最近有很多数据库也尝试着改善了 IN 的性能 A。也许未来的某一天,无论在哪个数据库上, IN 都能具备与 EXISTS 一样的性能。

EXPLAIN SELECT *
FROM `class_a`
WHERE NAME IN (SELECT NAME
FROM `class_b`);EXPLAIN SELECT *
FROM class_a A
WHERE EXISTS
(SELECT *
FROM class_b B
WHERE A.name = B.name);

2 避免排序

会进行排序的代表性的运算有下面这些。
●  GROUP BY 子句
●  ORDER BY 子句
●  聚合函数(SUM、 COUNT、 AVG、 MAX、 MIN)
●  DISTINCT
●  集合运算符(UNION、 INTERSECT、 EXCEPT)
●  窗口函数(RANK、 ROW_NUMBER 等)



使用 EXISTS 代替 DISTINCT

在极值函数中使用索引(MAX/MIN)
SQL 语言里有 MAX 和 MIN 两个极值函数。使用这两个函数时都会进行排序。但是如果参数字段上建有索引,则只需要扫描索引,不需要扫描整张表.这种方法并不是去掉了排序这一过程,而是优化了排序前的查找速度,从而减弱排序对整体性能的影响.

能写在 WHERE 子句里的条件不要写在 HAVING 子句里
原因通常有两个。第一个是在使用 GROUP BY 子句聚合时会进行排序,如果事先通过 WHERE 子
句筛选出一部分行,就能够减轻排序的负担。第二个是在 WHERE 子句的条
件里可以使用索引。 HAVING 子句是针对聚合后生成的视图进行筛选的,
但是很多时候聚合后的视图都没有继承原表的索引结构

在 GROUP BY 子句和 ORDER BY 子句中使用索引
一般来说, GROUP BY 子句和 ORDER BY 子句都会进行排序,来对行
进行排列和替换。不过,通过指定带索引的列作为 GROUP BY 和 ORDER
BY 的列,可以实现高速查询。特别是,在一些数据库中,如果操作对象
的列上建立的是唯一索引,那么排序过程本身都会被省略掉。如果各位有
兴趣,可以确认一下自己使用的数据库是否支持这个功能.

真的用到索引了吗

使用索引时,条件表达式的左侧应该是原始字段!!!

请牢记,这一点是在优化索引时首要关注的地方!!!


进行默认的类型转换

■ 对 char 类型的“col_1”列指定条件的示例
× SELECT * FROM SomeTable WHERE col_1 = 10;
○ SELECT * FROM SomeTable WHERE col_1 = ‘10’;
○ SELECT * FROM SomeTable WHERE col_1 = CAST(10, AS CHAR(2));

默认的类型转换不仅会增加额外的性能开销,还会导致索引不可用
可以说是有百害而无一利。虽然这样写还不至于出错,但还是不要嫌麻烦,在需要类型转换时显式地进行类型转换吧(别忘了转换要写在条件表达式的右边)

减少中间表
在 SQL 中,子查询的结果会被看成一张新表,这张新表与原始表一样,
可以通过代码进行操作。这种高度的相似性使得 SQL 编程具有非常强的
灵活性,但是如果不加限制地大量使用中间表,会导致查询性能下降。
频繁使用中间表会带来两个问题,一是展开数据需要耗费内存资源,
二是原始表中的索引不容易使用到(特别是聚合时)。因此,尽量减少中
间表的使用也是提升性能的一个重要方法

工作实战: 让 SQL 飞起来相关推荐

  1. 原理+实战掌握SQL注入方法

    本文首发于先知社区 原理+实战掌握SQL注入方法 前言: SQL注入是web安全中最常见的攻击方式,SQL注入有很多方法,但如果只知道payload,不知道原理,感觉也很难掌握,这次就总结一下我所遇到 ...

  2. 面试官系统精讲Java源码及大厂真题 - 47 工作实战:Socket 结合线程池的使用

    47 工作实战:Socket 结合线程池的使用 立志是事业的大门,工作是登堂入室的旅程. --巴斯德 引导语 Socket 面试最终题一般都是让你写一个简单的客户端和服务端通信的例子,本文就带大家一起 ...

  3. 实战 | flink sql 实时 TopN

    实战 | flink sql 实时 TopN 1.背景篇 2.难点剖析篇-此类指标建设.保障的难点 2.1.数据建设 2.2.数据保障 2.3.数据服务保障 3.数据建设篇-具体实现方案详述 3.1. ...

  4. linux性能优化实战 倪朋飞,Linux性能优化实战:系统的swap变高(09)

    一.实验环境 1.操作系统 root@openstack:~# lsb_release -a No LSB modules are available. Distributor ID:Ubuntu D ...

  5. 【微信小程序 - 工作实战分享】1.微信小程序发送手机短信验证码(阿里云)

    发送手机短信验证码 前言 一. 准备工作 二. 配置 三. 实战代码(仅仅是后台代码,前端传入手机号) 总结 前言 在网站和移动应用中利用短信验证码进行信息确认是最常用的验证手段.随着短信验证码的技术 ...

  6. (转)MySQL数据库的优化-运维架构师必会高薪技能,笔者近六年来一线城市工作实战经验...

    标签:服务器 数据库 老男孩 高薪技能 一线城市 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://liangweilinux.bl ...

  7. MySQL数据库的优化-运维架构师必会高薪技能,笔者近六年来一线城市工作实战经验...

    原文地址:http://liangweilinux.blog.51cto.com/8340258/1728131 首先在此感谢下我的老师-老男孩专家拥有16年一线实战经验,我当然不能和我的老师平起平坐 ...

  8. mysql 测试快生产慢_生产上MySQL慢查询优化实战,SQL优化实战

    之前看了饿了么团队写的一篇博客:等等!这两个 Spring-RabbitMQ 的坑我们已经替你踩了.深受启发,一定要取个能吸引读者眼球的标题,当然除了响当当的标题以外,内容也要是干货.为什么会想取这样 ...

  9. 两个sql交集_神奇的 SQL 之性能优化 → 让 SQL 飞起来

    写在前面 在像 Web 服务这样需要快速响应的应用场景中,SQL 的性能直接决定了系统是否可以使用:特别在一些中小型应用中,SQL 性能更是决定服务能否快速响应的唯一标准 严格地优化查询性能时,必须要 ...

最新文章

  1. java类的修饰词有哪些_Java类与对象及访问控制修饰词解析
  2. 目标还是中国人,纽约智慧城市项目想通过EB-5募资10亿
  3. python购物车程序-Python编写购物车程序
  4. ASP.NET 4 和 Visual Studio 2010 Web 开发概述
  5. 数据可视化的基本原理——视觉通道
  6. C/C++中预编译#,##,#error作用
  7. LintCode 1859. 最小振幅(排序)
  8. OSPF工作机制——OSPF邻居状态机详解(附图)
  9. yolov5安装pip install requirements.txt,pycocotools安装报错
  10. python怎么连接excel_python怎么连接excel
  11. 修复VC6.0打开菜单项以及添加工程菜单项
  12. android hardware解析
  13. Javashop 7.0 商城Https协议修改部分
  14. 信号与系统相关知识回顾总结
  15. ipv4 pxe 联想start_电脑开不了机提示start pxe over ipv4的解决方法
  16. 参考文献标引方式_参考文献的标注方法有哪些呢?
  17. poj1564 Sum it up
  18. 干货!基于常识图谱和混合策略的情绪支持对话系统
  19. 雨伞被拿错,你怎么办?!
  20. 运筹说 第6期|运筹学自媒体的“百家争鸣”

热门文章

  1. 为什么python不需要编译_为什么我用Go写机器学习部署平台,而偏偏不用Python?...
  2. 过拟合和欠拟合_现代深度学习解决方案中的两大挑战:拟合和欠拟合
  3. Java中==和equals、equals和hashCode的关系详解
  4. TIME_WAIT和CLOSE_WAIT
  5. spring配置jdbc连接oracle,mysql,sqlserver
  6. Java实现发送邮件(可配置)忘记密码,发送邮件
  7. 基于Windows下python3.4.1IDLE常用快捷键小结
  8. Python变量赋值的秘密
  9. 启动NASA“造导弹”,阿里为何要“上天”?
  10. java 信号量Semaphore