/images/hugo/avatar.png

14 MYSQL 全表扫描

全表扫描对 MySQL 有什么影响

1. 对 server 层的影响

1.1 发送数据的流程

取数据和发数据的流程是这样的:

  1. 获取一行,写到 net_buffer 中。这块内存的大小是由参数 net_buffer_length 定义的,默认是 16k。
  2. 重复获取行,直到 net_buffer 写满,调用网络接口发出去。
  3. 如果发送成功,就清空 net_buffer,然后继续取下一行,并写入 net_buffer。
  4. 如果发送成功,就清空 net_buffer,然后继续取下一行,并写入 net_buffer。

/images/mysql/MySQL45%E8%AE%B2/server_send.jpg

13 MYSQL 索引选择

MySQL 如何选择索引

1. 优化器逻辑

选择索引是优化器的工作。而优化器选择索引的目的,是找到一个最优的执行方案,并用最小的代价去执行语句。优化器会考虑扫描行数、是否使用临时表、是否排序等因素进行综合判断。对于普通索引来说,优化器需要把回表的代价算进去。

12 MySQL 问题追踪与性能优化

MySQL 中怎么做问题追踪与性能优化

1. 问题排查的工具

mysql 中有以下几种问题排查的工具:

  1. show processlist
  2. show engine innodb status
  3. information_schema.innodb_trx
  4. show engine innodb status
  5. optimizer_trace
  6. 慢查询日志
  7. performance_schema 和 sys 系统库

1.1 试验环境

接下来我们以下面的实现环境看看,如何使用这些工具排查 MySQL 的性能问题

11 SQL 一些常见的错误用法

对索引字段做函数操作,可能会破坏索引值的有序性,因此优化器就决定放弃走树搜索功能。

试验环境

我们用下面两张表作为我们测试 SQL 用法的试验环境:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
# 交易信息表
mysql> CREATE TABLE `tradelog` (
  `id` int(11) NOT NULL,
  `tradeid` varchar(32) DEFAULT NULL,
  `operator` int(11) DEFAULT NULL,
  `t_modified` datetime DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `tradeid` (`tradeid`),
  KEY `t_modified` (`t_modified`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

# 交易详情表
mysql> CREATE TABLE `trade_detail` (
  `id` int(11) NOT NULL,
  `tradeid` varchar(32) DEFAULT NULL,
  `trade_step` int(11) DEFAULT NULL, /*操作步骤*/
  `step_info` varchar(32) DEFAULT NULL, /*步骤信息*/
  PRIMARY KEY (`id`),
  KEY `tradeid` (`tradeid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

1.条件字段函数操作

类似下面的 SQL,对索引字段做了函数操作,可能会破坏索引值的有序性,因此优化器就决定放弃走树搜索功能。

10 MySQL如何显示随机消息

random 存在哪些问题

背景

从一个单词表中随机选出三个单词。这个表的建表语句和初始数据的命令如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20

mysql> CREATE TABLE `words` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `word` varchar(64) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB;

delimiter ;;
create procedure idata()
begin
  declare i int;
  set i=0;
  while i<10000 do
    insert into words(word) values(concat(char(97+(i div 1000)), char(97+(i % 1000 div 100)), char(97+(i % 100 div 10)), char(97+(i % 10))));
    set i=i+1;
  end while;
end;;
delimiter ;

call idata();

1. 方法一: order by rand()

1.1 内存临时表

select word from words order by rand() limit 3; 这个语句的意思很直白,但执行流程却有点复杂的。