mysql
2020-09-24 11:04:28 1 举报
mysql原理与调优学习笔记
作者其他创作
大纲/内容
1、哈希索引
4、优化特定类型的查询
查询优化器
动态对performance_schema进行配置的配置表
语句事件记录表。这些表记录了语句事件信息,当前语句事件表events_statements_current、历史语句事件表events_statements_history和长语句历史事件表events_statements_history_long、以及聚合后的摘要表summary,其中,summary表还可以根据帐号(account),主机(host),程序(program),线程(thread),用户(user)和全局(global)再进行细分)
案例
每次提交时写入os buffer,并调用fsync()
key_len
time,相应命令执行时间
1、如果一个索引包含所有需要查询的字段的值,我们称之为覆盖索引。2、不是所有类型的索引都可以称为覆盖索引,覆盖索引必须要存储索引列的值。3、不同的存储实现覆盖索引的方式不同,不是所有的引擎都支持覆盖索引,memory不支持覆盖索引。
单次传输排序先读取查询所需要的所有列,然后再根据给定列进行排序,最后直接返回排序结果,此方式只需要一次顺序IO读取所有的数据,而无须任何的随机IO,问题在于查询的列特别多的时候,会占用大量的存储空间,无法存储大量的数据
4、hash分区
set profiling=1;
子查询的优化最重要的优化建议是尽可能使用关联查询代替。
1、网络2、CPU3、IO4、上下文切换5、系统调用6、生成统计信息7、锁等待时间
数据类型的优化
show status like 'Handler_read%';Handler_read_first:读取索引第一个条目的次数Handler_read_key:通过index获取数据的次数Handler_read_last:读取索引最后一个条目的次数Handler_read_next:通过索引读取下一条数据的次数Handler_read_prev:通过索引读取上一条数据的次数Handler_read_rnd:从固定位置读取数据的次数Handler_read_rnd_next:从数据节点读取下一条数据的次数
连接器
性能监控
1、一个表最多只能有1024个分区,在5.7版本的时候可以支持8196个分区。2、在早期的mysql中,分区表达式必须是整数或者是返回整数的表达式,在mysql5.5中,某些场景可以直接使用列来进行分区。3、如果分区字段中有主键或者唯一索引的列,那么所有主键列和唯一索引列都必须包含进来。4、分区表无法使用外键约束。
5、key分区
redo log
·整数类型可以使用的几种整数类型:TINYINT,SMALLINT,MEDIUMINT,INT,BIGINT分别使用8,16,24,32,64位存储空间。尽量使用满足需求的最小数据类型 ·字符和字符串类型1、char长度固定,即每条数据占用等长字节空间;最大长度是255个字符,适合用在身份证号、手机号等定长字符串2、varchar可变长度,可以设置最大长度;最大空间是65535个字节,适合用在长度可变的属性3、text不设置长度,当不知道属性的最大长度时,适合用text按照查询速度:char>varchar>text ·varchar根据实际内容长度保存数据1、使用最小的符合需求的长度。2、varchar(n) n小于等于255使用额外一个字节保存长度,n>255使用额外两个字节保存长度。3、varchar(5)与varchar(255)保存同样的内容,硬盘存储空间相同,但内存空间占用不同,是指定的大小 。(如,长度为5的字符串,两者硬盘空间相同,内存后者会更大)4、varchar在mysql5.6之前变更长度,或者从255一下变更到255以上时时,都会导致锁表。 ·char固定长度的字符串1、最大长度:2552、会自动删除末尾的空格3、检索效率、写效率 会比varchar高,以空间换时间
监控文件系统层调用的表
磁盘数据读入内存
log buffer
log files
id
查询缓存
内核空间
5、优化union查询
4、覆盖索引
info,详细的sql语句
当执行查询语句的时候,会先去查询缓存中查看结果,之前执行过的sql语句及其结果可能以key-value的形式存储在缓存中,如果能找到则直接返回,如果找不到,就继续执行后续阶段。
阶段事件记录表。记录语句执行的阶段事件的表
合理使用范式
根据表的统计信息及索引使用情况,大致估算出找出所需记录需要读取的行数,此参数很重要,直接反应的sql找了多少数据,在完成目的的情况下越少越好
监视内存使用的表
sleep:线程正在等待客户端发送新的请求
3、聚簇索引与非聚簇索引
type
但是,不推荐使用查询缓存:- 1、查询缓存的失效比较频繁,只要表更新,缓存就会清空。- 2、缓存对应新更新的数据命中率比较低。
一、show profiles
3、列分区
分析器
MySQL的performance schema 用于监控MySQL server在一个较低级别的运行过程中的资源消耗、资源等待等情况。instruments: 生产者,用于采集mysql中各种各样的操作产生的事件信息,对应配置表中的配置项我们可以称为监控采集配置项。 consumers:消费者,对应的消费者表用于存储来自instruments采集的数据,对应配置表中的配置项我们可以称为消费存储配置项。
1、优化count()查询
show tables like '%memory%';
idselect查询的序列号,包含一组数字,表示查询中执行select子句或者操作表的顺序1、如果id相同,那么执行顺序从上到下。2、如果id不同,如果是子查询,id的序号会递增,id值越大优先级越高,越先被执行。3、id相同和不同的,同时存在:相同的可以认为是一组,从上往下顺序执行,在所有组中,id值越大,优先级越高,越先执行。
user,操作的用户
·BLOB和TEXT类型MySQL 把每个 BLOB 和 TEXT 值当作一个独立的对象处理。两者都是为了存储很大数据而设计的字符串类型,分别采用二进制和字符方式存储。 ·datetime和timestampdatetime\t占用8个字节\t与时区无关,数据库底层时区配置,对datetime无效\t可保存到毫秒\t可保存时间范围大\t不要使用字符串存储日期类型,占用空间大,损失日期类型函数的便捷性timestamp\t占用4个字节\t时间范围:1970-01-01到2038-01-19\t精确到秒\t采用整形存储\t依赖数据库设置的时区\t自动更新timestamp列的值date\t占用的字节数比使用字符串、datetime、int存储要少,使用date类型只需要3个字节\t使用date类型还可以利用日期时间函数进行日期之间的计算\tdate类型用于保存1000-01-01到9999-12-31之间的日期
客户端
db,操作的数据库
除非确实需要服务器消除重复的行,否则一定要使用union all,因此没有all关键字,mysql会在查询的时候给临时表加上distinct的关键字,这个操作的代价很高
聚簇索引不是单独的索引类型,而是一种数据存储方式,指的是数据行跟相邻的键值紧凑的存储在一起。非聚簇索引数据文件跟索引文件分开存放。
show tables like '%wait%';
3、执行过程的优化
紫色表示在innodb内部执行的操作,非紫色表示在执行器中执行。需要注意的是:redo log写入时拆分为两个阶段的操作,prepare和commit阶段。
显示索引的哪一列被使用了,如果可能的话,是一个常数
一、范式优点:1、范式化的更新通常比反范式要快。2、当数据较好的范式化后,很少或者没有重复的数据。3、范式化的数据比较小,可以放在内存中,操作比较快。 缺点:通常需要进行关联查询。二、反范式优点:1、所有数据都在同一张表中,避免关联查询。2、可以设计有效的索引。缺点:表格内的冗余较多,删除数据时候会造成有些有用的信息丢失。
binlog 是server层的日志,主要做mysql功能层面的事情。与redo log的区别:1、redo是innodb独有的,binlog是所有引擎都可以使用的。2、redo是物理日志,记录的是在某个数据页上做了什么修改,binlog是逻辑日志,记录的是这个语句的原始逻辑。3、redo是循环写的,空间会用完,binlog是可以追加写的,不会覆盖之前的日志信息。一般在企业中数据库会有备份系统,可以定期执行备份,备份周期可以自己设置。数据恢复过程:1、找到最近一次的全量备份。2、从备份的时间点开始,将备份的binlog取出来,重放到要恢复的那个时刻。
1、基于哈希表的实现,只有精确匹配索引所有列的查询才有效。2、在mysql中,只有memory的存储引擎显式支持哈希索引。3、哈希索引自身只需存储对应的hash值,所以索引的结构十分紧凑,这让哈希索引查找的速度非常快。
1、当发生数据修改的时候,innodb引擎会先将记录写到redo log中,并更新内存,此时更新就算是完成了,同时innodb引擎会在合适的时机将记录操作到磁盘中。2、redo log是固定大小的,是循环写的过程。3、有了redo log之后,innodb就可以保证即使数据库发生异常重启,之前的记录也不会丢失,叫做crash-safe。
查询优化处理
B+树
1、undo log是为了实现事务的原子性,在mysql数据库innodb存储引擎中,还用undo log来实现多版本并发控制(MVCC)。2、在操作任何数据之前,首先将数据备份到一个地方(这个存储数据备份的地方称为undo log)。然后进行数据的修改。如果出现了错误或者用户执行了ROLLBACK语句,系统可以利用undo log中的备份将数据恢复到事务开始之前的状态。3、注意:undo log是逻辑日志,可以理解为:
B+树是在B树的基础上做的一种优化:1、B+树每个节点可以包含更多的节点,一是因为为了降低树的高度,二是因为要将数据范围变为多个区间,区间越多检索越快。2、非叶子节点仅存储key,叶子节点存储key和数据3、叶子节点两两指针相互连接(符合磁盘的预读特性),顺序查询性能更高。参考:https://www.cxyxiaowu.com/3726.html
补充:Block Nested-Loop Join(1)Join Buffer会缓存所有参与查询的列而不是只有Join的列。(2)可以通过调整join_buffer_size缓存大小(3)join_buffer_size的默认值是256K,join_buffer_size的最大值在MySQL 5.1.22版本前是4G-1,而之后的版本才能在64位操作系统下申请大于4G的Join Buffer空间。(4)使用Block Nested-Loop Join算法需要开启优化器管理配置的optimizer_switch的设置block_nested_loop为on,默认为开启。show variables like '%optimizer_switch%'
count()是特殊的函数,有两种不同的作用,一种是某个列值的数量,也可以统计行数。
存储引擎层
当包含多个列作为索引,需要注意的是正确的顺序依赖于该索引的查询,同时需要考虑如何更好的满足排序和分组的需要
DML操作
possible_keys
analyzing and statistics:线程正在收集存储引擎的统计信息,并生成查询的执行计划
sorting result:线程正在对结果集进行排序
用户自定义变量是一个容易被遗忘的mysql特性,但是如果能够用好,在某些场景下可以写出非常高效的查询语句,在查询中混合使用过程化和关系话逻辑的时候,自定义变量会非常有用。用户自定义变量是一个用来存储内容的临时容器,在连接mysql的整个过程中都存在。
索引数据,并分离热点如果数据有明显的热点,而且除了这部分数据,其他数据很少被访问到,那么可以将这部分热点数据单独放在一个分区中,让这个分区的数据能够有机会都缓存在内存中,这样查询就可以只访问一个很小的分区表,能够使用索引,也能够有效的使用缓存。
自定义变量的案例
我在马士兵教育的学习笔记
用户空间
优化器
减少因回表查询列的次数。
2、优化关联查询
每次提交时写入os buffer,每秒调用fsync()刷到磁盘
连接器:管理连接,权限验证分析器:词法分析,语法分析 优化器:执行计划,索引选择 执行器:操作引擎,返回结果存储引擎:存储数据,提供读写接口
分区表的应用场景
获取数据
排序算法
redo log buffer
2
提交事务,处于commit阶段
--在配置文件中修改performance_schema的属性值,on表示开启,off表示关闭[mysqld]performance_schema=ON--查看performance_schema的属性mysql> SHOW VARIABLES LIKE 'performance_schema';
1
select * from emp;
写入redo log,处于prepare阶段
query:线程正在执行查询或正在将结果发送给客户端
关于索引
select_type
1、范围分区(Range)
undo log file
1、null值会使分区过滤无效。2、分区列和索引列不匹配,会导致查询无法进行分区过滤。3、选择分区的成本可能很高。4、打开并锁住所有底层表的成本可能很高。5、维护分区的成本可能很高。
show tables like '%statement%';
mysql的关联查询很重要,但其实关联查询执行的策略比较简单:mysql对任何关联都执行嵌套循环关联操作,即mysql先在一张表中循环取出单条数据,然后再嵌套到下一个表中寻找匹配的行,依次下去,直到找到所有表中匹配的行为止。然后根据各个表匹配的行,返回查询中需要的各个列。mysql会尝试再最后一个关联表中找到所有匹配的行,如果最后一个关联表无法找到更多的行之后,mysql返回到上一层次关联表,看是否能够找到更多的匹配记录,以此类推迭代执行。整体的思路如此,但是要注意实际的执行过程中有多个变种形式:
undo log buffer
binlog
数据更新流程
表示索引中使用的字节数,可以通过key_len计算查询中使用的索引长度,在不损失精度的情况下长度越短越好。
show tables like '%setup%';
语法解析器和预处理
performance_schema实践操作
fsync()
redo log file
5、索引监控
服务端
哈希表
commit
优化器的优化策略一、静态优化直接对解析树进行分析,并完成优化。二、动态优化动态优化与查询的上下文有关,也可能跟取值、索引对应的行数有关mysql对查询的静态优化只需要一次,但对动态优化在每次执行时都需要重新评估
show profile for query 1;
当语法树没有问题之后,相应的要由优化器将其转成执行计划,一条查询语句可以使用非常多的执行方式,最后都可以得到对应的结果,但是不同的执行方式带来的效率是不同的,优化器的最主要目的就是要选择最有效的执行计划mysql使用的是基于成本的优化器,在优化的时候会尝试预测一个查询使用某种查询计划时候的成本,并选择其中成本最小的一个
案例二:避免重新查询刚刚更新的数据当需要高效的更新一条记录的时间戳,同时希望查询当前记录中存放的时间戳是什么。update t1 set lastupdated = now() where id = 1 and @now:=now();select @now;
数据页在内存
自定义比变量的限制1、无法使用查询缓存。2、不能在使用常量或者标识符的地方使用自定义变量。例如表明、列明或者limit子句。3、用户自定义变量的生命周期是一个连接中有效,所以不能用它们来做连接间的通信。4、不能显式地声明自定义变量的类型。5、mysql优化器在某些场景下可能会将这些变量优化掉,这可能导致代码不按预想的 方式运行。6、赋值符号 := 的优先级非常低,所以在使用赋值表达式的时候应该明确的使用括号。7、使用未定义变量不会产生任何语法错误。
mysql 架构图
sending data:线程可能在多个状态之间传送数据,或者在生成结果集或者向客户端返回数据
B树
os buffer
3、优化子查询
等待事件记录表。与语句事件类型的相关记录表类似
show tables like '%stage%';
优势
更改数据
id,session id
1、大大减少了服务器需要扫描的数据量。2、帮助服务器避免排序和临时表。3、将随机io变成顺序io
写入新数据
字符集的选择
buffer pool
show tables like '%file%';
show profiles;
state,命令执行状态
索引采用的数据结构
索引优化
一、连接器负责跟客户端建立连接,获取权限、维持和管理连接:- 用户名密码验证- 查询权限信息,分配对应的权限- 可以用show processlist查看现在的连接- 如果太长时间没有动静,就会自动断开,通过wait_timeout控制,默认8小时二、连接可以分为两类:- 长连接:推荐使用,但是要周期性的断开长连接- 短连接
rows
当需要排序的列的总大小超过max_length_for_sort_data定义的字节,mysql会选择双次排序,反之使用单次排序,当然,用户可以设置此参数的值来选择排序的方式
1、更小的通常更好确保没有低估需要存储的值的范围,选择最小数据类型。2、简单就好如:(1)数值。整型 > 字符串;(2)日期时间。mysql自建类型 > 字符串;(3)IP。整型 > 字符串;3、尽量避免null尽量,不强求,看业务。
1、哈希索引只包含哈希值和行指针,而不存储字段值,索引不能使用索引中的值来避免读取行。2、哈希索引数据并不是按照索引值顺序存储的,所以无法进行排序。3、哈希索引不支持部分列匹配查找,哈希索引是使用索引列的全部内容来计算哈希值。4、哈希索引支持等值比较查询,不支持任何范围查询。5、访问哈希索引的数据非常快,除非有很多哈希冲突,当出现哈希冲突的时候,存储引擎必须遍历链表中的所有行指针,逐行进行比较,直到找到所有符合条件的行。6、哈希冲突比较多的话,维护的代价也会很高
实际使用的索引,如果为null,则没有使用索引,查询中若使用了覆盖索引,则该索引和查询的select字段重叠。
command,当前状态
代理主键与业务无关,无意义的数字序列。如自增id。自然主键事物属性中的自然唯一标识。如身份证ID。推荐使用代理主键1、它们不与业务耦合,因此更容易维护2、一个大多数表,最好是全部表,通用的键策略能够减少需要编写的源码数量,减少系统的总体拥有成本
locked:在mysql的服务层,该线程正在等待表锁
host,操作的主机
特点:1、所有键值分布在整棵树中。2、搜索有可能在非叶子节点结束。3、每个节点最多拥有m个子树(m阶树)4、根节点至少有两个子树。5、分支节点至少有m/2棵子树(根节点、子节点除外)6、所有叶子节点都在同一层、每个节点最多可以有m-1个key,并且以升序排列。参考:https://www.jianshu.com/p/8b653423c586
key
schema与数据类型优化
自定义变量的使用set @one :=1set @min_actor :=(select min(actor_id) from actor)set @last_week :=current_date-interval 1 week;
type显示的是访问类型,访问类型表示我是以何种方式去访问我们的数据,最容易想的是全表扫描,直接暴力的遍历一张表去寻找需要的数据,效率非常低下,访问的类型有很多,效率从最好到最坏依次是:system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL
innodb engine
在使用分区表的时候需要注意的问题
6、推荐使用用户自定义变量
关联查询Simple Nested-Loop Join(简单嵌套循环连接)相当于两个for循环,对数据库开销较大。Index Nested-Loop Join(索引嵌套循环连接)非驱动表(右表)上有索引,可以通过索引来减少比较,加速查询。Block Nested-Loop Join(Mysql5.6版本引入该优化,针对SNL)当右表没有索引,会采用BNL。引入join buffer缓冲区,将驱动表的所有join相关的列都缓存到join buffer中,然后批量与匹配表进行匹配,将第一种多次比较合并为一次,降低非驱动表(右表)的访问频率。join_buffer_size默认256k。
1.纯拉丁字符能表示的内容,没必要选择 latin1 之外的其他字符编码,因为这会节省大量的存储空间。2.如果我们可以确定不需要存放多种语言,就没必要非得使用UTF8(utf8mb4)或者其他UNICODE字符类型,这回造成大量的存储空间浪费。3.MySQL的数据类型可以精确到字段,所以当我们需要大型数据库中存放多字节数据的时候,可以通过对不同表不同字段使用不同的数据类型来较大程度减小数据存储量,进而降低 IO 操作次数并提高缓存命中率。
1、主键索引2、唯一索引3、普通索引4、全文索引5、组合索引
索引用处
分区表
在很多应用场景中我们需要将数据进行分页,一般会使用limit加上偏移量的方法实现,同时加上合适的orderby 的子句,如果这种方式有索引的帮助,效率通常不错,否则需要进行大量的文件排序操作。还有一种情况,当偏移量非常大的时候,前面的大部分数据都会被抛弃,这样的代价太高。要优化这种查询的话,要么是在页面中限制分页的数量,要么优化大偏移量的性能。
4、优化limit分页
磁盘
索引优点
案例一:优化排名语句span style=\"font-size: inherit;\
mysql通过关键字将SQL语句进行解析,并生成一颗解析树,mysql解析器将使用mysql语法规则验证和解析查询,例如验证使用使用了错误的关键字或者顺序是否正确等等,预处理器会进一步检查解析树是否合法,例如表名和列名是否存在,是否有歧义,还会验证权限等等
写binlog
哈希表(Hash Table,也叫散列表),是根据关键码值 (Key-Value) 而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。哈希表的实现主要需要解决两个问题,哈希函数和冲突解决。哈希函数:尽可能不重复地生成数组下标。哈希冲突:开放地址法、链地址法、再哈希法、公共溢出区法。
包含额外的信息。
mysql> show processlist;+----+------+-----------------+------+---------+------+-------+------------------+| Id | User | Host | db | Command | Time | State | Info |+----+------+-----------------+------+---------+------+-------+------------------+| 2 | root | 127.0.0.1:54524 | NULL | Query | 0 | init | show processlist |+----+------+-----------------+------+---------+------+-------+------------------+1 row in set (0.00 sec)
show tables like '%transaction%';
1、范围分区2、列表分区3、列分区4、hash分区5、key分区6、子分区
全量扫描数据,不要任何索引使用简单的分区方式存放表,不要任何索引,根据分区规则大致定位需要的数据为止,通过使用where条件将需要的数据限制在少数分区中,这种策略适用于以正常的方式访问大量数据。
分区表的限制
事务事件记录表。记录事务相关的事件的表
2、优化数据访问
1、查询慢的原因
1、表非常大以至于无法全部都放在内存中,或者只在表的最后部分有热点数据,其他均是历史数据。2、分区表的数据更容易维护。- 批量删除大量数据可以使用清除整个分区的方式。- 对一个独立分区进行优化、检查、修复等操作。3、分区表的数据可以分布在不同的物理设备上,从而高效地利用多个硬件设备。4、可以使用分区表来避免某些特殊的瓶颈。- innodb的单个索引的互斥访问。- ext3文件系统的inode锁竞争。5、可以备份和恢复独立的分区。
一、在具体执行SQL语句之前,要先经过优化器的处理。- 当表中有多个索引的时候,决定用哪个索引- 当sql语句需要做多表关联的时候,决定表的连接顺序-等等二、不同的执行方式对SQL语句的执行效率影响很大。- RBO:基于规则的优化- CBO:基于成本的优化
mysql查询完缓存之后会经过以下几个步骤:解析SQL、预处理、优化SQL执行计划,这几个步骤出现任何的错误,都可能会终止查询
新数据更新到内存
查询优化
6、子分区
执行计划
此工具默认是禁用的,可以通过服务器变量在绘画级别动态的修改当设置完成之后,在服务器上执行的所有语句,都会测量其耗费的时间和其他一些查询执行状态变更相关的数据。在mysql的命令行模式下只能显示两位小数的时间,可以使用如下命令查看具体的执行时间执行如下命令可以查看详细的每个步骤的时间:
2、列表分区
主键的选择
索引分类
extra
1、查询性能低下的主要原因是访问的数据太多,某些查询不可避免的需要筛选大量的数据,我们可以通过减少访问数据量的方式进行优化。2、是否向数据库请求了不需要的数据。
优化策略:1、总有人认为myisam的count函数比较快,这是有前提条件的,只有没有任何where条件的count(*)才是比较快的。2、使用近似值。在某些应用场景中,不需要完全精确的值,可以参考使用近似值来代替,比如可以使用explain来获取近似的值。其实在很多OLAP的应用中,需要计算某一个列值的基数,有一个计算近似值的算法叫hyperloglog。3、更复杂的优化。一般情况下,count()需要扫描大量的行才能获取精确的数据,其实很难优化,在实际操作的时候可以考虑使用索引覆盖扫描,或者增加汇总表,或者增加外部缓存系统。
三、show processlist
显示可能应用在这张表中的索引,一个或多个,查询涉及到的字段上若存在索引,则该索引将被列出,但不一定被查询实际使用
如何使用分区表
all: 显示所有性能信息show profile all for query nblock io:显示块io操作的次数show profile block io for query ncontext switches:显示上下文切换次数,被动和主动show profile context switches for query ncpu:显示用户cpu时间、系统cpu时间show profile cpu for query nIPC:显示发送和接受的消息数量show profile ipc for query nMemory:暂未实现page faults:显示页错误数量show profile page faults for query nsource:显示源码中的函数名称与位置show profile source for query nswaps:显示swap的次数show profile swaps for query n
面试技术名词
select count(*) from film_actor;show status like 'last_query_cost';可以看到这条查询语句大概需要做1104个数据页才能找到对应的数据,这是经过一系列的统计信息计算来的
2、组合索引
0
当需要存储大量的URL,并且根据URL进行搜索查找,如果使用B+树,存储的内容就会很大select id from url where url=\"\"也可以利用将url使用CRC32做哈希,可以使用以下查询方式:select id fom url where url=\"\" and url_crc=CRC32(\"\")此查询性能较高原因是使用体积很小的索引来完成查找
1、确保on或者using子句中的列上有索引,在创建索引的时候就要考虑到关联的顺序。2、确保任何的groupby和order by中的表达式只涉及到一个表中的列,这样mysql才有可能使用索引来优化这个过程。
一、词汇分析:Mysql需要把输入的字符串进行识别每个部分代表什么意思。- 把字符串 T 识别成表名 T- 把字符串 ID 识别成列 ID二、语法分析:- 根据语法规则判断这个sql语句是否满足mysql的语法,如果不符合就会报错“you have an error in your SQL synta”
undo log
Copying to tmp table:线程正在执行查询,并且将其结果集都复制到一个临时表中
1、哈希表2、B+树
二、performance schema
使用show processlist查看连接的线程个数,来观察是否有大量线程处于不正常的状态或者其他不正常的特征
ref
执行器
返回数据
分区表的类型
内存
- 当delete一条记录时,undo log会记录一条对应insert记录- 当insert一条记录时,undo log会记录一条对应delete记录- 当update一条记录时,undo log会记录一条相反的update记录
哈希索引的限制
如果需要从非常大的表中查询出某一段时间的记录,而这张表中包含很多年的历史数据,数据是按照时间排序的,此时应该如何查询数据呢?因为数据量巨大,肯定不能在每次查询的时候都扫描全表。考虑到索引在空间和维护上的消耗,也不希望使用索引,即使使用索引,会发现会产生大量的碎片,还会产生大量的随机IO,但是当数据量超大的时候,索引也就无法起作用了,此时可以考虑使用分区来进行解决。
两次传输排序第一次数据读取是将需要排序的字段读取出来,然后进行排序,第二次是将排好序的结果按照需要去读取数据行。这种方式效率比较低,原因是第二次读取数据的时候因为已经排好序,需要去读取所有记录而此时更多的是随机IO,读取数据成本会比较高两次传输的优势,在排序的时候存储尽可能少的数据,让排序缓冲区可以尽可能多的容纳行数来进行排序操作
在很多情况下mysql会选择错误的执行计划,原因如下:1、执行计划的成本估算不等同于实际执行的成本。2、mysql的最优可能跟你想的不一样。3、mysql不考虑其他并发执行的查询。4、mysql不会考虑不受其控制的操作成本
table
0 条评论
下一页