Mysql高级(事务、索引)

Mysql中查询缓存优化

开启Mysql的查询缓存,当执行完全相同的SQL语句的时候,服务器就会直接从缓存中读取结果,当数据被修改,之前的缓存会失效,修改比较频繁的表不适合做查询缓存。

步骤如下:

  1. 客户端发送一条查询给服务器;
  2. 服务器先会检查查询缓存,如果命中了缓存,则立即返回存储在缓存中的结果。否则进入下一阶段;
  3. 服务器端进行SQL解析、预处理,再由优化器生成对应的执行计划;
  4. MySQL根据优化器生成的执行计划,调用存储引擎的API来执行查询;
  5. 将结果返回给客户端。

1、查询缓存配置

#查看当前的MySQL数据库是否支持查询缓存
SHOW VARIABLES LIKE 'have_query_cache';   #查看当前MySQL是否开启了查询缓存
SHOW VARIABLES LIKE 'query_cache_type';#查看查询缓存的占用大小
SHOW VARIABLES LIKE 'query_cache_size';#查看查询缓存的状态变量
SHOW STATUS LIKE 'Qcache%';

各个变量的含义如下:

参数 含义
Qcache_free_blocks 查询缓存中的可用内存块数
Qcache_free_memory 查询缓存的可用内存量
Qcache_hits 查询缓存命中数
Qcache_inserts 添加到查询缓存的查询数
Qcache_lowmen_prunes 由于内存不足而从查询缓存中删除的查询数
Qcache_not_cached 非缓存查询的数量(由于 query_cache_type 设置而无法缓存或未缓存)
Qcache_queries_in_cache 查询缓存中注册的查询数
Qcache_total_blocks 查询缓存中的块总数

2、开启查询缓存

MySQL的查询缓存默认是关闭的,需要手动配置参数 query_cache_type ,来开启查询缓存。可取值有三个 :

含义
OFF 或 0 查询缓存功能关闭
ON 或 1 查询缓存功能打开,SELECT的结果符合缓存条件即会缓存,否则,不予缓存,显式指定 SQL_NO_CACHE,不予缓存
DEMAND 或 2 查询缓存功能按需进行,显式指定 SQL_CACHE 的SELECT语句才会缓存;其它均不予缓存

在 /usr/my.cnf 配置中,增加以下配置 : query_cache_type =1

配置完毕之后,重启服务既可生效 ;

验证:执行一条比较耗时的SQL语句,然后再多执行几次,查看后面几次的执行时间;也可以通过查看查询缓存的缓存命中数,来判定是否走查询缓存。

3、查询缓存SELECT选项

可以在SELECT语句中指定两个与查询缓存相关的选项 :

  1. SQL_CACHE : 如果查询结果是可缓存的,并且 query_cache_type 系统变量的值为ON或 DEMAND
    ,则缓存查询结果 。

  2. SQL_NO_CACHE : 服务器不使用查询缓存。它既不检查查询缓存,也不检查结果是否已缓存,也不缓存查询结果。

例子:

SELECT SQL_CACHE id, name FROM customer;
SELECT SQL_NO_CACHE id, name FROM customer;

4、查询缓存失效的情况

1) SQL 语句不一致的情况, 要想命中查询缓存,查询的SQL语句必须一致。

SQL1 : select count(*) from tb_item;
SQL2 : Select count(*) from tb_item;

2) 当查询语句中有一些不确定的时,则不会缓存。如 : now() , current_date() , curdate() , curtime() , rand() , uuid() , user() , database() 。

SQL1 : select * from tb_item where updatetime < now() limit 1;
SQL2 : select user();
SQL3 : select database();

3) 不使用任何表查询语句。

select 'A';

4) 查询 mysql, information_schema或 performance_schema 数据库中的表时,不会走查询缓存。

select * from information_schema.engines;

5) 在存储的函数,触发器或事件的主体内执行的查询。

6) 如果表更改,则使用该表的所有高速缓存查询都将变为无效并从高速缓存中删除。这包括使用MERGE映射到已更改表的表的查询。一个表可以被许多类型的语句,如被改变 INSERT, UPDATE, DELETE, TRUNCATE TABLE, ALTER TABLE, DROP TABLE,或 DROP DATABASE 。

注意:Mysql8.0已去掉缓存功能,原因是任何对表的修改都会导致这些表的所有缓存无效,这样缓存命中率非常的低,影响数据库性能

Mysql一些重要参数

1、innodb_buffer_pool_size

该变量决定了 innodb 存储引擎表数据和索引数据的最大缓存区大小。在保证操作系统及其他程序有足够内存可用的情况下,innodb_buffer_pool_size 的值越大,缓存命中率越高,访问InnoDB表需要的磁盘I/O 就越少,性能也就越高。

innodb_buffer_pool_size=512M

2、innodb_log_buffer_size

决定了innodb重做日志缓存的大小,对于可能产生大量更新记录的大事务,增加innodb_log_buffer_size的大小,可以避免innodb在事务提交前就执行不必要的日志写入磁盘操作。

innodb_log_buffer_size=10M

3、max_connections

此参数控制允许连接到MySQL数据库的最大数量,默认值是 151。如果状态变量 connection_errors_max_connections 不为零,并且一直增长,则说明不断有连接请求因数据库连接数已达到允许最大值而失败,这时可以考虑增大max_connections 的值。

Mysql 最大可支持的连接数,取决于很多因素,包括给定操作系统平台的线程库的质量、内存大小、每个连接的负荷、CPU的处理速度,期望的响应时间等。

4、back_log

控制MySQL监听TCP端口时设置的积压请求栈大小。如果MySql的连接数达到max_connections时,新来的请求将会被存在堆栈中,以等待某一连接释放资源,该堆栈的数量即back_log,如果等待连接的数量超过back_log,将不被授予连接资源,将会报错。

如果需要数据库在较短的时间内处理大量连接请求, 可以考虑适当增大back_log 的值。

5、table_open_cache

该参数用来控制所有SQL语句执行线程可打开表缓存的数量, 而在执行SQL语句时,每一个SQL执行线程至少要打开 1 个表缓存。该参数的值应该根据设置的最大连接数 max_connections 以及每个连接执行关联查询中涉及的表的最大数量来设定 :max_connections x N ;

6、thread_cache_size

为了加快连接数据库的速度,MySQL 会缓存一定数量的客户服务线程以备重用,通过参数 thread_cache_size 可控制 MySQL 缓存客户服务线程的数量。

7、innodb_lock_wait_timeout

该参数是用来设置InnoDB 事务等待行锁的时间,默认值是50ms , 可以根据需要进行动态设置。对于需要快速反馈的业务系统来说,可以将行锁的等待时间调小,以避免事务长时间挂起; 对于后台运行的批量处理程序来说, 可以将行锁的等待时间调大, 以避免发生大的回滚操作。

Mysql锁

锁是计算机协调多个进程或线程并发访问某一资源的机制(避免争抢)。

在数据库中,除传统的计算资源(如 CPU、RAM、I/O 等)的争用以外,数据也是一种供许多用户共享的资源。

如何保证数据并发访问的一致性、有效性是所有数据库必须解决的一个问题,锁冲突也是影响数据库并发访问性能的一个重要因素。从这个角度来说,锁对数据库而言显得尤其重要,也更加复杂。

从对数据操作的粒度分 :

  1. 表锁:操作时,会锁定整个表。
  2. 行锁:操作时,会锁定当前操作行。

从对数据操作的类型分:

  1. 读锁(共享锁):针对同一份数据,多个读操作可以同时进行而不会互相影响。
  2. 写锁(排它锁):当前操作没有完成之前,它会阻断其他写锁和读锁。
锁类型 特点
表级锁 偏向MyISAM 存储引擎,开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低。
行级锁 偏向InnoDB 存储引擎,开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高

1、行锁

InnoDB 实现了以下两种类型的行锁。

  • 共享锁(S):又称为读锁,简称S锁,是在执行读取操作的时候创建的。若事务T对数据A加上S锁,则事务T只能读A;其他事务只能再对A加S锁,而不能加X锁,直到T释放A上的S锁。这就保证了其他事务可以读A,但在T释放A上的S锁之前不能对A做任何修改。

  • 排他锁(X):又称为写锁,简称X锁,排他锁就是不能与其他锁并存,如一个事务获取了一个数据行的排他锁,其他事务就不能再获取该行的其他锁,包括共享锁和排他锁,但是获取排他锁的事务是可以对数据就行读取和修改。

对于UPDATE、DELETE和INSERT语句,InnoDB会自动给涉及数据集加排他锁(X);

对于普通SELECT语句,InnoDB不会加任何锁;

测试:

create table test_innodb_lock(id int(11),name varchar(16),sex varchar(1)
)engine = innodb default charset=utf8;insert into test_innodb_lock values(1,'100','1');
insert into test_innodb_lock values(3,'3','1');
insert into test_innodb_lock values(4,'400','0');
insert into test_innodb_lock values(5,'500','1');
insert into test_innodb_lock values(6,'600','0');
insert into test_innodb_lock values(7,'700','0');
insert into test_innodb_lock values(8,'800','1');
insert into test_innodb_lock values(9,'900','1');
insert into test_innodb_lock values(1,'200','0');create index idx_test_innodb_lock_id on test_innodb_lock(id);
create index idx_test_innodb_lock_name on test_innodb_lock(name);
Session-1 Session-2
关闭自动提交功能 关闭自动提交功能
可以正常的查询出全部的数据 可以正常的查询出全部的数据
查询id 为3的数据 查询id 为3的数据
更新id为3的数据,但是不提交; 更新id为3 的数据, 处于等待状态
通过commit, 提交事务 解除阻塞,更新正常进行
更新id为3数据,正常的获取到行锁 , 执行更新 由于与Session-1 操作不是同一行,获取当前行锁,执行更新

2、意向锁

意向锁的目的是为了表明某个事务正在锁定一行或者将要锁定一行,意向锁是表级锁;

申请意向锁的动作是数据库完成的,就是说,事务A申请一行的行锁的时候,数据库会自动先开始申请表的意向锁

意向锁有两种:

  1. 意向共享锁(IS)表示事务意图在表中的单个行上设置共享锁。
  2. 意向排他锁(IX)表明事务意图在表中的单个行上设置独占锁。

我们先了解一下意向锁是在什么时候使用的。

  • 在一个事务对一张表的某行添加S锁之前,它必须对该表获取一个IS锁。
  • 在一个事务对一张表的某行添加X锁之前,它必须对该表获取一个IX锁。

数据库里面是同时允许锁表,或者锁行的。如果事务A需要修改某一行数据,则他会给该行加X锁。

这时事务B想申请整个表的X锁做某些操作。他能否申请成功呢?不能,因为申请成功则代表事务B可以对任意行做读写。显然这与事务A冲突了。

那这时数据库应该怎么判断呢?

可行方案就是,逐行判断是否加了X锁,如果都没加,就代表可以锁表,如果其中某一行加上了X锁,那么就不能整表加锁,不过,显然这样效率实在是太低了…

这个时候来看意向锁,就可以看出他发挥了重要的重要:

事务A想对某行上X锁之前,必须要获得到表的IX锁,现在没有其他事务使用IX锁,所以事务A获取成功。

事务A——获得IX锁——对某行上X锁

这个时候事务B想对这个表上X锁,发现IX表已经被拿走了,证明目前有其他事务正在修改该表的某行或者多行,此时事务B被阻塞…

意向锁之间是相互兼容的,IX,IS是表级锁,不会和行级的X,S锁发生冲突。只会和表级的X,S发生冲突

事务A加了表的IX锁,或者IS锁,只代表事务A已锁定一行或者将要锁定一行。事务B当然也可以锁定其他的行,所以事务B肯定也是可以获得表的IS锁或者IX锁的。


举个例子:

  • 事务A已经获得了IS锁,想要读取某行数据,事务B想要获得表的S锁,可以获得成功,因为读是兼容的
  • 事务B获得了表的IX锁,想要修改某行数据,事务B想要获得表的X锁,但是由于IX锁已被获取走,证明有其他事务正在修改某行数据,所以事务B获得失败,只能被组塞住…

3、无索引行锁升级为表锁

如果不通过索引条件检索数据,那么InnoDB将对表中的所有记录加锁,实际效果跟表锁一样。

# name字段为varchar,不加' '则索引失效
UPDATE test_innodb_lock set sex = '2' where name = 900;

4、间隙锁

当我们用范围条件,而不是使用相等条件检索数据,并请求共享或排他锁时,InnoDB会给符合条件的已有数据进行加锁; 对于键值在条件范围内但并不存在的记录,叫做 “间隙(GAP)” , InnoDB也会对这个 “间隙” 加锁,这种锁机制就是所谓的 间隙锁(Next-Key锁) 。

间隙:比如范围条件为 where id < 7,现在id存在1、2、3、5、7,那么对于id 为4和6就称作间隙;

例如:

#Session-1执行更新语句,并且事务未提交时
UPDATE test_innodb_lock set sex = '2' where id <4 ;#Session-2执行插入语句会出现阻塞状态。
INSERT INTO test_innode_lock VALUES(2,'200','1')

5、InnoDB 行锁争用情况

show  status like 'innodb_row_lock%';

Innodb_row_lock_current_waits: 当前正在等待锁定的数量Innodb_row_lock_time: 从系统启动到现在锁定总时间长度Innodb_row_lock_time_avg:每次等待所花平均时长Innodb_row_lock_time_max:从系统启动到现在等待最长的一次所花的时间Innodb_row_lock_waits: 系统启动后到现在总共等待的次数当等待的次数很高,而且每次等待的时长也不小的时候,我们就需要分析系统中为什么会有如此多的等待,然后根据分析结果着手制定优化计划。

SQL执行顺序

编写顺序

SELECT DISTINCT<select list>
FROM<left_table> <join_type>
JOIN<right_table> ON <join_condition>
WHERE<where_condition>
GROUP BY<group_by_list>
HAVING<having_condition>
ORDER BY<order_by_condition>
LIMIT<limit_params>

执行顺序

FROM <left_table>ON        <join_condition><join_type>     JOIN    <right_table>WHERE        <where_condition>GROUP BY     <group_by_list>HAVING     <having_condition>SELECT DISTINCT     <select list>ORDER BY <order_by_condition>LIMIT     <limit_params>

Mysql 日志

在任何一种数据库中,都会有各种各样的日志,记录着数据库工作的方方面面,以帮助数据库管理员追踪数据库曾经发生过的各种事件。MySQL 也不例外,在 MySQL 中,有 4 种不同的日志,分别是错误日志、二进制日志(BINLOG 日志)、查询日志和慢查询日志,这些日志记录着数据库在不同方面的踪迹。

错误日志

错误日志是 MySQL 中最重要的日志之一,它记录了当 mysqld 启动和停止时,以及服务器在运行过程中发生任何严重错误时的相关信息。当数据库出现任何故障导致无法正常使用时,可以首先查看此日志。

该日志是默认开启的 , 默认存放目录为 mysql 的数据目录(var/lib/mysql), 默认的日志文件名为 hostname.err(hostname是主机名)。

查看日志位置指令 :

show variables like 'log_error%';

查看日志内容 :

二进制日志

二进制日志(BINLOG)记录了所有的 DDL(数据定义语言)语句和 DML(数据操纵语言)语句,但是不包括数据查询语句。此日志对于灾难时的数据恢复起着极其重要的作用,MySQL的主从复制, 就是通过该binlog实现的。

二进制日志,默认情况下是没有开启的,需要到MySQL的配置文件中开启,并配置MySQL日志的格式。

配置文件位置 : /usr/my.cnf

日志存放位置 : 配置时,给定了文件名但是没有指定路径,日志默认写入Mysql的数据目录。

#配置开启binlog日志, 日志的文件前缀为 mysqlbin -----> 生成的文件名如 : mysqlbin.000001,mysqlbin.000002
log_bin=mysqlbin#配置二进制日志的格式
binlog_format=STATEMENT

二进制日志格式有以下三种:

1、STATEMENT

该日志格式在日志文件中记录的都是SQL语句(statement),每一条对数据进行修改的SQL都会记录在日志文件中,通过Mysql提供的mysqlbinlog工具,可以清晰的查看到每条语句的文本。主从复制的时候,从库(slave)会将日志解析为原文本,并在从库重新执行一次。

2、ROW

该日志格式在日志文件中记录的是每一行的数据变更,而不是记录SQL语句。比如,执行SQL语句 : update tb_book set status=‘1’ , 如果是STATEMENT 日志格式,在日志中会记录一行SQL文件; 如果是ROW,由于是对全表进行更新,也就是每一行记录都会发生变更,ROW 格式的日志中会记录每一行的数据变更。

3、MIXED

这是目前MySQL默认的日志格式,即混合了STATEMENT 和 ROW两种格式。默认情况下采用STATEMENT,但是在一些特殊情况下采用ROW来进行记录。MIXED 格式能尽量利用两种模式的优点,而避开他们的缺点。

日志读取

由于日志以二进制方式存储,不能直接读取,需要用mysqlbinlog工具来查看,语法如下 :

mysqlbinlog log-file;

查看STATEMENT格式日志

执行插入语句 :

insert into tb_book values(null,'Lucene','2088-05-01','0');

mysqlbin.index : 该文件是日志索引文件 , 记录日志的文件名;

mysqlbing.000001 :日志文件

查看日志内容 :

mysqlbinlog mysqlbing.000001;

查看ROW格式日志

配置 :

#配置开启binlog日志, 日志的文件前缀为 mysqlbin -----> 生成的文件名如 : mysqlbin.000001,mysqlbin.000002
log_bin=mysqlbin#配置二进制日志的格式
binlog_format=ROW

插入数据 :

insert into tb_book values(null,'SpringCloud实战','2088-05-05','0');

如果日志格式是 ROW , 直接查看数据 , 是查看不懂的 ; 可以在mysqlbinlog 后面加上参数 -vv

mysqlbinlog -vv mysqlbin.000002

日志删除

对于比较繁忙的系统,由于每天生成日志量大 ,这些日志如果长时间不清楚,将会占用大量的磁盘空间。下面我们将会讲解几种删除日志的常见方法 :

方式一

通过 Reset Master 指令删除全部 binlog 日志,删除之后,日志编号,将从 xxxx.000001重新开始 。

查询之前 ,先查询下日志文件 :
执行删除日志指令:

Reset Master

方式二

执行指令 purge master logs to 'mysqlbin.******',该命令将删除 ******编号之前的所有日志。

方式三

执行指令 purge master logs before 'yyyy-mm-dd hh24:mi:ss',该命令将删除日志为 “yyyy-mm-dd hh24:mi:ss” 之前产生的所有日志 。

方式四

设置参数 --expire_logs_days=# ,此参数的含义是设置日志的过期天数, 过了指定的天数后日志将会被自动删除,这样将有利于减少DBA 管理日志的工作量。

配置如下 :

查询日志

查询日志中记录了客户端的所有操作语句,而二进制日志不包含查询数据的SQL语句。

默认情况下, 查询日志是未开启的。如果需要开启查询日志,可以设置以下配置 :

#该选项用来开启查询日志 , 可选值 : 0 或者 1 ; 0 代表关闭, 1 代表开启
general_log=1#设置日志的文件名 , 如果没有指定, 默认的文件名为 host_name.log
general_log_file=file_name

在 mysql 的配置文件 /usr/my.cnf 中配置如下内容 :
配置完毕之后,在数据库执行以下操作 :

select * from tb_book;
select * from tb_book where id = 1;
update tb_book set name = 'lucene入门指南' where id = 5;
select * from tb_book where id < 8;

执行完毕之后, 再次来查询日志文件 :

慢查询日志

慢查询日志记录了所有执行时间超过参数 long_query_time 设置值并且扫描记录数不小于 min_examined_row_limit 的所有的SQL语句的日志。long_query_time 默认为 10 秒,最小为 0, 精度可以到微秒。

慢查询日志默认是关闭的 。可以通过两个参数来控制慢查询日志 :

# 该参数用来控制慢查询日志是否开启, 可取值: 1 和 0 , 1 代表开启, 0 代表关闭
slow_query_log=1 # 该参数用来指定慢查询日志的文件名
slow_query_log_file=slow_query.log# 该选项用来配置查询的时间限制, 超过这个时间将认为值慢查询, 将需要进行日志记录, 默认10s
long_query_time=10

日志的读取

和错误日志、查询日志一样,慢查询日志记录的格式也是纯文本,可以被直接读取。

1) 查询long_query_time 的值。

2) 执行查询操作

select id, title,price,num ,status from tb_item where id = 1;

由于该语句执行时间很短,为0s , 所以不会记录在慢查询日志中。
该SQL语句 , 执行时长为 26.77s ,超过10s , 所以会记录在慢查询日志文件中。

3) 查看慢查询日志文件

直接通过cat 指令查询该日志文件 :
如果慢查询日志内容很多, 直接查看文件,比较麻烦, 这个时候可以借助于mysql自带的 mysqldumpslow 工具, 来对慢查询日志进行分类汇总。

Mysql复制

复制是指将主数据库的DDL 和 DML 操作通过二进制日志传到从库服务器中,然后在从库上对这些日志重新执行(也叫重做),从而使得从库和主库的数据保持同步。

MySQL支持一台主库同时向多台从库进行复制, 从库同时也可以作为其他从服务器的主库,实现链状复制。

1、复制原理

MySQL 的主从复制原理如下。


从上层来看,复制分成三步:

  • 从库会生成两个线程,一个I/O线程,一个SQL线程;
  • I/O线程会去请求主库的binlog,并将得到的binlog写到本地的relay-log(中继日志)文件中;
  • 主库的更新操作(update、insert、delete)会写到binlog;
  • SQL线程,会读取relay log文件中的日志,并解析成sql语句逐一执行;

MySQL 复制的有点主要包含以下三个方面:

  • 主库出现问题,可以快速切换到从库提供服务。

  • 可以在从库上执行查询操作,从主库中更新,实现读写分离,降低主库的访问压力。

  • 可以在从库中执行备份,以避免备份期间影响主库的服务。

2、搭建步骤

master

1) 在master 的配置文件(/usr/my.cnf)中,配置如下内容:

#mysql 服务ID,保证整个集群环境中唯一
server-id=1#mysql binlog 日志的存储路径和文件名
log-bin=/var/lib/mysql/mysqlbin#错误日志,默认已经开启
#log-err#mysql的安装目录
#basedir#mysql的临时目录
#tmpdir#mysql的数据存放目录
#datadir#是否只读,1 代表只读, 0 代表读写
read-only=0#忽略的数据, 指不需要同步的数据库
binlog-ignore-db=mysql#指定同步的数据库
#binlog-do-db=db01

2) 执行完毕之后,需要重启Mysql:

service mysql restart ;

3) 创建同步数据的账户,并且进行授权操作:

grant replication slave on *.* to 'itcast'@'192.168.192.131' identified by 'itcast';  flush privileges;

4) 查看master状态:

show master status;字段含义:
File : 从哪个日志文件开始推送日志文件
Position : 从哪个位置开始推送日志
Binlog_Ignore_DB : 指定不需要同步的数据库

slave

1) 在 slave 端配置文件中,配置如下内容:

#mysql服务端ID,唯一
server-id=2#指定binlog日志
log-bin=/var/lib/mysql/mysqlbin

2) 执行完毕之后,需要重启Mysql:

service mysql restart;

3) 执行如下指令 :

change master to master_host= '192.168.192.130', master_user='itcast', master_password='itcast', master_log_file='mysqlbin.000001', master_log_pos=413;

指定当前从库对应的主库的IP地址,用户名,密码,从哪个日志文件开始的那个位置开始同步推送日志。

4) 开启同步操作

start slave;show slave status;

5) 停止同步操作

stop slave;

验证同步操作

1) 在主库中创建数据库,创建表,并插入数据 :

2) 在从库中查询数据,进行验证 :

在从库中,可以查看到刚才创建的数据库:

Mysql服务启动后停止问题


首先,需要把原服务删除:

mysqld --remove mysql

然后,重新安装mysql服务

mysqld --install mysql

初始化data目录。如果在与bin目录同级的文件夹下没有data文件夹的话,则创建一个data空目录,名字务必为data。如果有该目录的话,记得要清空data目录下的所有文件

执行初始化(-insecure表示无密码)

mysqld –initialize-insecure

启动服务

net start mysql

登陆mysql

Mysql 中 MyISAM 和 InnoDB 的区别有哪些?

  1. InnoDB 支持事务,MyISAM 不支持事务;
  2. InnoDB 支持外键,而 MyISAM 不支持。对一个包含外键的 InnoDB 表转为 MYISAM 会失败;
  3. InnoDB 是聚集索引,MyISAM 是非聚集索引。聚簇索引的文件存放在主键索引的叶子节点上,因此 InnoDB 必须要有主键,通过主键索引效率很高。但是辅助索引需要两次查询,先查询到主键,然后再通过主键查询到数据。因此,主键不应该过大,因为主键太大,其他索引也都会很大。而 MyISAM 是非聚集索引,数据文件是分离的,索引保存的是数据文件的指针。主键索引和辅助索引是独立的;
  4. InnoDB 不保存表的具体行数,执行 select count(*) from table 时需要全表扫描。而MyISAM 用一个变量保存了整个表的行数,执行上述语句时只需要读出该变量即可,速度很快;
  5. InnoDB 最小的锁粒度是行锁,MyISAM 最小的锁粒度是表锁。一个更新语句会锁住整张表,导致其他查询和更新都会被阻塞,因此并发访问受限;
  6. MyISAM允许没有任何索引和主键的表存在,索引都是保存行的地址。InnoDB:如果没有设定主键或者非空唯一索引,就会自动生成一个6字节的主键(用户不可见),数据是主索引的一部分,附加索引保存的是主索引的值;

Innodb表中在没有默认主键的情况下会生成一个6byte空间的自动增长主键,可以用select _rowid from table来查询。当在表里设置了主键之后,_rowid就是对应主键,select _rowid from table查询的是对应的主键值.

总结

上一篇Mysql高级(一)传送门

本文仅总结笔记作后续复习理解使用,如果有侵犯到原作者,请第一时间通知我,我会进行处理!!!

本文参考资料:

  • 如何理解数据库事务中的一致性的概念?
  • 数据库索引到底是什么,是怎样工作的?
  • Mysql 中 MyISAM 和 InnoDB 的区别有哪些?
  • MySQL 连接的使用 | 菜鸟教程
  • 2020最新MySQL高级教程
  • 意向锁

Mysql高级(锁、日志)相关推荐

  1. MySQL高级 - 锁 - MyISAM表锁 - 读锁

    如何加表锁 MyISAM 在执行查询语句(SELECT)前,会自动给涉及的所有表加读锁,在执行更新操作(UPDATE.DELETE.INSERT 等)前,会自动给涉及的表加写锁,这个过程并不需要用户干 ...

  2. MySQL高级 - 锁 - MySQL对锁的支持

    Mysql 锁 相对其他数据库而言,MySQL的锁机制比较简单,其最显著的特点是不同的存储引擎支持不同的锁机制.下表中罗列出了各存储引擎对锁的支持情况: 存储引擎 表级锁 行级锁 页面锁 MyISAM ...

  3. MySQL高级 - 锁 - InnoDB行锁 - 介绍及背景知识

    行锁介绍 行锁特点 :偏向InnoDB 存储引擎,开销大,加锁慢:会出现死锁:锁定粒度最小,发生锁冲突的概率最低,并发度也最高. InnoDB 与 MyISAM 的最大不同有两点:一是支持事务:二是 ...

  4. MySQL高级篇——日志

    一.简介 1. 分类 Mysql有不同的日志文件,用来存储不同类型和功能的日志,分为二进制日志.错误日志.通用查询日志.慢查询日志.Mysql8.0又新增两种日志:中继日志和数据定义语句日志. 2. ...

  5. MySQL高级 - 锁 - InnoDB行锁 - 总结

    InnoDB存储引擎由于实现了行级锁定,虽然在锁定机制的实现方面带来了性能损耗可能比表锁会更高一些,但是在整体并发处理能力方面要远远由于MyISAM的表锁的.当系统并发量较高的时候,InnoDB的整体 ...

  6. MySQL高级 - 锁 - InnoDB行锁 - 争用情况查看

    InnoDB 行锁争用情况 show status like 'innodb_row_lock%'; Innodb_row_lock_current_waits: 当前正在等待锁定的数量Innodb_ ...

  7. MySQL高级 - 锁 - InnoDB行锁 - 间隙锁危害

    隙锁危害 当我们用范围条件,而不是使用相等条件检索数据,并请求共享或排他锁时,InnoDB会给符合条件的已有数据进行加锁: 对于键值在条件范围内但并不存在的记录,叫做 "间隙(GAP)&qu ...

  8. MySQL高级 - 锁 - InnoDB行锁 - 行锁升级为表锁

    无索引行锁升级为表锁 如果不通过索引条件检索数据,那么InnoDB将对表中的所有记录加锁,实际效果跟表锁一样. 查看当前表的索引 : show index from test_innodb_lock ...

  9. MySQL高级 - 锁 - InnoDB行锁 - 基本演示

    案例准备工作 create table test_innodb_lock(id int(11),name varchar(16),sex varchar(1) )engine = innodb def ...

  10. MySQL高级 - 锁 - InnoDB行锁 - 类型

    InnoDB 的行锁模式 InnoDB 实现了以下两种类型的行锁. 共享锁(S):又称为读锁,简称S锁,共享锁就是多个事务对于同一数据可以共享一把锁,都能访问到数据,但是只能读不能修改. 排他锁(X) ...

最新文章

  1. 《微信跳一跳》安卓手机刷分软件搭建及攻略
  2. pycharm新建文件夹时新建python package和新建directory有什么区别?
  3. Spring Rmi配置
  4. Unity/DotNetty中集成Lidgren实现可靠UDP
  5. 基于链路思想的SpringBoot单元测试快速写法
  6. Soulver:不光会算,还懂你所言的计算器
  7. linux 弱口令扫描,弱口令扫描神器XSCAN 一款经典弱口令扫描软件 可搜索各种端口(3389等) 各种系统(XP WIN7等) - 下载 - 搜珍网...
  8. Pytorch GAN实战 MINIST手写数字识别分布解析
  9. 程序员客栈v4.21:多一个作品便多一份工作机会
  10. Teradata天睿公司发布开源Kylo软件
  11. 【windows系统】插入移动硬盘后,有盘符,但提示需要格式化的解决办法
  12. h5 数字变化_那些H5用到的技术(6)——数字滚动特效
  13. wpsa4排版_WPS如何快速排版
  14. 怎么用python表白_如何正确使用Python进行表白
  15. layui内置模块(element常用元素操作)
  16. 新思维研究生英语第1-12单元 课文翻译习题答案
  17. A. Unusual Competitions
  18. Win10 安装软件报错:管理员已阻止你运行此应用
  19. 均方误差(MSE)根均方误差(RMSE)平均绝对误差(MAE)
  20. 使用Python实现从CAD中选择多段线并提取坐标

热门文章

  1. Cadence OrCAD Capture 将Port信息从底层更新到顶层的方法
  2. 记录第一次安装Python环境
  3. Spinnaker 初探
  4. # Odoo丨一文让你弄懂Odoo的用户、组与权限
  5. flowable 并行节点跳转以及驳回
  6. 预算500~1000元,新手入门吉他应该怎么选?
  7. Camunda Modeler汉化添加简体中文和繁体中文支持
  8. 拉普拉斯算子从笛卡尔坐标系到圆柱坐标系下的推导过程
  9. 热点:软件测试真的会被ChatGPT代替吗?
  10. Eslint快速入门和使用技巧-教程