想要得到更好的表现,你须要: 合理的表结构 + 出色的索引 + [ 不错的查询语句]
不少时候你其实在向数据库请求了超多资源,可能你并无意识到,这些多余的数据会被抛弃,并给MySQL服务器端增长额外的压力。 一些场景:html
-- 使用索引
EXPLAIN SELECT * FROM users WHERE id = 1\G
********************** 1.row **********************
type: ref
key : id
rows: 10
-- 删除索引
EXPLAIN SELECT * FROM users WHERE id = 1\G
********************** 1.row ***********************
type: ALL
rows: 5073
extra: Using Where
复制代码
咱们能够经过"EXPLAIN" 命令看看这条命令是怎么执行的,有没有索引扫描内容真的差异太大mysql
在表面上,咱们都直接在 SQL 语句加上WHERE就完事儿,并不过多的去关心性能问题,可是即便你们都是WHERE, 在"索引" 的辅助下也会存在很大的优劣之分sql
由好到差:数据库
总结一下,不管是方法1.存储引擎能直接访问须要的行,仍是2.直接前往B-Tree读数,都好过全表扫描,返回全部数据而后由MySQL作过滤。 为了达到这样的效果,尽量把要用到的WHERE筛选项放到索引中去缓存
为了更好的作出优化,以及后面会提到的"缓存命中",咱们必须也要先知道查询过程是怎样的。 关于详细的步骤,咱们会在下面的环节描述一下各个部件是怎么工做的bash
MySQL客户端与MySQL服务器之间的交互是半双工的,也就是说同一时刻内只有其中一方向另外一方发送请求,这个请求能够是客户端向服务器发送SQL语句,也能够是服务器向客户端返回所请求的数据,一旦客户端发送了请求之后,它所能作的就只有等待服务器返回所请求的数据服务器
在解析一个SQL语句以前服务器会先看看是否有命中缓存中的数据,也就是看看是否已经有缓存上了。检查的标准是经过对查询语句的哈希实现的,若是哈希出的结果是同样的就算命中,而且这个哈希是对大小写敏感的,也就是说哪怕是大小写不一致都不能算命中性能
MySQL服务器经过关键字将客户端发来的SQL语句进行解析,解析器经过MYSQL语法对这条语句进行验证,例如它将验证是否使用了错误的关键字,关键字顺序是否正确等。优化
预处理器则会去检查它所请求的数据表以及列是否存在,并验证权限。spa
走到了这一步说明你的语句没有问题,能执行,问题就是怎么执行。 因此查询优化器,会先找出不少个可能的作法,并尝试找出最优解 优化原则? 找出成本最低的
mysql > SELECT SQL_NO_CACHE COUNT(*) FROM users
+----------+
| count(*) |
+----------+
| 5462 |
+----------+
mysql > SHOW STATUS LIKE 'Last_query_cost'
+-----------------+-------------+
| Variable_name | Value |
+-----------------+-------------+
| Last_query_cost | 1040.59 |
+-----------------+-------------+复制代码
2.5.1 先简单介绍一下联表的执行过程 (若是你知道就能够跳过了)
-- 上图反应的就是下面个SQL语句的联表过程
SELECT tbl1.col1 , tbl2.col2
FROM tbl1 JOIN tbl2 USING(col3)
WHERE tbl1.col1 IN(5,6)复制代码
表之间的关联遵循一种"嵌套" 的规则,用最简单的话说就是先取表[tbl1]的第一行,去表[tbl2]中作匹配,对于咱们,咱们天然是但愿执行的步骤越少越好:
2.5.2 联表优化实战分析
SELECT tbl1.col1, tbl2.col2, tbl3.col3
FROM tbl1
INNER JOIN tbl2 USING(tbl1.col1)
INNER JOIN tbl3 USING(tbl3.col3);复制代码