客户端发出sql –> 连接器校验身份 —> 服务层 —>
语法分析
- 词法分析和语法分析是两步。词法分析把字符串拆成token
(识别出SELECT、FROM、WHERE这些关键字),语法分析检查这些token的组合是否符合SQL语法规则, 做这件事的组件叫解析器(Parser)。它最终产出一棵语法树(AST)。
查询缓存
- 表一次更新缓存全部作废, 写多命中率低, 维护缓存成本大
优化器
- 优化器评估的是每种执行方案的IO成本和CPU成本。读多少页数据、
比较多少行,综合算出一个数值,选最小的那个方案。
- 小表接大表
- 假设A表10行,B表1000行。
A驱动B:外层扫10行,每行去B表查一次,查10次。
B驱动A:外层扫1000行,每行去A表查一次,查1000次。
如果被驱动表的连接字段上有索引,每次查的代价差不多。那外层循环次数越
少,总代价越小。
所以小表驱动大表本质上是在减少外层循环次数。
- Explain
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| EXPLAIN SELECT * FROM user WHERE name = '张三';
+----+-------------+-------+------+---------------+----------+---------+-------+------+-------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+------+---------------+----------+---------+-------+------+-------+ | 1 | SIMPLE | user | ref | idx_name | idx_name | 102 | const | 3 | NULL | +----+-------------+-------+------+---------------+----------+---------+-------+------+-------+ ┌───────────────┬────────────────────────────────────────────────────────────────────────────────────┐ │ 字段 │ 含义 │ ├───────────────┼────────────────────────────────────────────────────────────────────────────────────┤ │ id │ 查询编号,子查询或UNION时会有多行,id越大越先执行 │ ├───────────────┼────────────────────────────────────────────────────────────────────────────────────┤ │ select_type │ 查询类型,SIMPLE=简单查询,SUBQUERY=子查询,DERIVED=派生表 │ ├───────────────┼────────────────────────────────────────────────────────────────────────────────────┤ │ table │ 当前行在访问哪张表 │ ├───────────────┼────────────────────────────────────────────────────────────────────────────────────┤ │ type │ 访问类型,性能从好到差:const > eq_ref > ref > range > index > ALL │ ├───────────────┼────────────────────────────────────────────────────────────────────────────────────┤ │ possible_keys │ 这条查询可能用到的索引有哪些 │ ├───────────────┼────────────────────────────────────────────────────────────────────────────────────┤ │ key │ 优化器最终选了哪个索引,NULL就是没用索引 │ ├───────────────┼────────────────────────────────────────────────────────────────────────────────────┤ │ key_len │ 用到了索引的多少字节,联合索引时可以判断用了几个字段 │ ├───────────────┼────────────────────────────────────────────────────────────────────────────────────┤ │ ref │ 索引列跟什么比较,const=常量,字段名=关联查询的连接字段 │ ├───────────────┼────────────────────────────────────────────────────────────────────────────────────┤ │ rows │ 预估扫描行数,越小越好 │ ├───────────────┼────────────────────────────────────────────────────────────────────────────────────┤ │ Extra │ 额外信息,重点关注:Using index(好)、Using filesort(差)、Using temporary(差) │ └───────────────┴────────────────────────────────────────────────────────────────────────────────────┘
|