35. Buffer Pool 设置
innodb_buffer_pool_size设置Buffer Pool的大小。
建议将除了连接使用的内存,操作系统使用的内存
之外的全部内存给Buffer Pool,不要靠操作系统的
OS Cache来缓冲缓存数据。
经验参考值:
n 48G内存:32G Buffer Pool
n 32G内存:20G Buffer Pool
n 24G内存:16G Buffer Pool
n 16G内存:10G Buffer Pool
66. JOIN 算法概述
Ø MySQL只有一 JOIN算法:Nested Loop Join
Ø Nested Loop Join:选择一张驱动表,用 联字
段循环匹配被驱动表
! FOR EACH ROW row1 IN table1 {
! FOR EACH ROW row2 IN table2 IF( 联条件) {
! result := row1 || row2;
! OUTPUT result;
! } }
Ø 支持条件下推(Push Down):先用条件过滤驱动
表和被驱动表,再把过滤后的结果集进行JOIN
67. 内连接
Ø 假定我们有一个如下形式的表T1、T2、T3的联
接查询:SELECT * FROM t1 INNER JOIN t2 ON c1(t1,t2) INNER JOIN
t3 ON c2 (t2,t3) WHERE c(t1,t2,t3)
Ø MySQL首先由优化器判定JOIN顺序,假设生成
执行计 为t1驱动t2驱动t3:
! FOR EACH ROW row1IN t1 IF (c(t1)){
! FOR EACH ROW row2 IN t2 IF (c1(t1,t2) && c(t2)) {
! FOR EACH ROW row3 IN t3 IF (c2(t2,t3) && c(t3)) {
! result := row1 || row2 || row3;
! OUTPUT result;
! } } }
Ø 将行传给下一层被驱动表匹配时,先用条件进行
过滤, 少参与JOIN的行数
68. 外连接
Ø SQL同前例:
! FOR EACH ROW row1 IN t1 IF c1(t1) {
! BOOL f1 := FALSE;
! FOR EACH ROW row2 IN t2 IF c1(t1,t2) AND (f1 ? c2(t2) : TRUE) {
! BOOL f2 := FALSE;
! FOR EACH ROW row3 IN t3 IF c2(t2,t3) AND (f1&&f2 ? c3(t3) : TRUE) {
! IF (f1&&f2 ? TRUE : (c2(t2) AND c3(t3))) {
! result := row1 || row2 || row3; OUTPUT result; }
! f2 := TRUE; f1 := TRUE; }
! IF (!f2) {
! IF (f1 ? TRUE : c2(t2) && c(t1,t2,NULL)) {
! result := row1 || row2 || NULL; OUTPUT t; }
! f1 := TRUE; } }
! IF (!f1 && c(t1,NULL,NULL)) {
! result := row1||NULL||NULL; OUTPUT t; } }
Ø 经过测试,三张10000行的表用外连接平均比内
连接慢0.01s,内连接效率高于外连接。
70. MySQL 优化器概述
Ø MySQL优化器属于RBO(基于规则的优化器),
5.1版本后带有少量的CBO(基于 销的优化器)
特性。
Ø MySQL优化器缺陷:
n 不支持函数索引:WHERE func(col) = x 无法使用col字段上
的索引
n 不支持索引过滤 (Index Filter) 但支持索引覆盖扫描:
n SELECT col1,col2,col3,col4 FROM t WHERE col1 > x AND col2 < y AND col3 >z; 无法利用
(col1,col2,col3)索引过滤col2和col3,需要回表查询。
n SELECT col1,col2,col3 FROM t WHERE col1 > x AND col2 < y AND col3 >z; 可以利用
(col1,col2,col3)索引扫描到col1,col2,col3的值不用回表。
n 无法自动优化子查询:MySQL无法将子查询优化为JOIN方式,
而是将子查询存为临时表(无索引),在外层SQL需要时调
用临时表数据进行匹配,这是效率非常低的执行方式,所以
尽量避免在SQL中使用子查询。
72. MySQL 优化器判定算法
Ø MySQL利用索引的原则:尽可能用主键索引>尽
可能筛去更多的数据>尽可能使用⻓长度小的索引>
尽可能使用更多索引列。
! idx_Col1索引⻓长度368,过滤基数9000
! idx_Col3索引⻓长度128,过滤基数3000
! idx_Col1_Col2索引⻓长度768,过滤基数11000
! idx_Col2_Col3索引⻓长度255,过滤基数 9000
! SELECT Col1, Col2, Col3 FROM t WHERE col1 = x AND col2 = y AND col3
= z;
! 优先使用idx_Col2_Col3索引,因为过滤基数差不多,索引⻓长度小得多。
! SELECT Col1, Col2, Col3 FROM t WHERE col1 = x AND col3 = z;
! 优先使用idx_Col1索引,因为col1过滤基数远大于col3,而idx_Col1_Col2因
为索引⻓长度⻓长的多过滤基数却相近则不被使用