MySQL高阶知识点

MySQL

文章目录

  • MySQL
    • char和varchar的区别
    • 视图
      • 视图的特点
    • 存储过程
      • 存储过程的特点
    • 触发器
      • 触发器的特点
    • MySQL引擎
    • 索引
      • 为什么要有索引呢?
      • 什么是索引
      • 索引的优势
      • 索引的劣势
      • 索引类型
      • 索引种类
      • 组合索引最左前缀原则
      • 索引创建原则
      • B树和B+树的区别
      • 数据库为什么使用B+树而不是B树
      • 聚簇索引和非聚簇索引
        • 聚簇索引
        • 非聚簇索引
    • 数据库事务
      • MySQL事务处理主要有两种方法
      • 事务隔离级别
        • 为什么要有隔离级别?
        • 设置隔离级别为*未提交读*(read uncommitted):
        • 设置*提交读隔离级别*(read committed):
        • 设置*可重复读隔离级别*(repeatable read):
        • 设置串行化(serializable)
    • 事务实现的原理
      • 原子性实现原理
      • 持久性实现原理
    • 隔离级别实现原理MVCC
      • MVCC是什么?
      • ReadView 是什么
    • 锁机制
      • 行锁、间隙锁、表锁
        • 行锁
        • 间隙锁
        • 表锁
      • 共享锁(s)
      • 排他锁(X)
    • SQL优化

char和varchar的区别

1.长度可变性

varchar类型用于存储可变长度的字符串,比固定长度类型更加节省空间。有一种情况除外:如果MySQL表使用ROW_FORMAT=FIXED创建的话,每一行都会使用定长存储。

char类型用于存储定长字符串。

2.存储方式

varchar需要1或者2个额外字节记录字符串的长度:如果列的最大长度小于或者等于255字节,则只用使用1个字节表示,否则需要两个字节表示。VARCHAR节省了存储空间,所以对性能也有帮助。但是,由于行是变长的,在UPDATE时可能使行变得比原来更长,这就导致需要做额外的工作。如果一个行占用的空间增长,并且在页内没有更多的空间可以存储,在这种情况下,不同的存储引擎的处理方式是不一样的。例如,MylSAM会将行拆成不同的片段存储,InnoDB则需要分裂页来使行可以放进页内。

char适合存储很短或者长度近似的字符串。例如密码的MD5值,因为这是一个定长值。对于经常改变的值,char要比varchar好,因为定长的char类型不容易产生碎片。对于非常短的列,char在空间存储上比varcahr更有效率,例如用char(1)来存储只有Y和N的值,如果采用单字节字符集只需要一个字节,但是varchar(1)却需要两个字节,因为还有一个记录长度的额外字节。

视图

视图是虚拟的表。与包含数据的表不一样,视图只包含使用时动态索引数据的查询。

创建视图:视图用create view语句来创建。

/*CREATE VIEW 视图名称 AS SQL查询语句*/
CREATE VIEW view1 AS
SELECTaccount,admin.name aname,role.name rname
FROMadmin,admin_role,ROLE
WHERE admin.`id` = admin_role.adminidAND admin_role.`roleid` = role.`id`

执行语句:

SELECT * FROM view1

修改:

#方式一:
CREATE OR REPLACE VIEW 视图名
AS
查询语句;
#方式二:
ALTER VIEW 视图名
AS
查询语句;

删除语句

DROP VIEW 视图1,视图2,...;

视图的特点

  1. 简化sql语句
  2. 提高SQL的重用性
  3. 保护基本表数据,提高了安全性

小结:

视图为虚拟的表。它包含的不是数据而是根据需要检索数据的查询。视图提供了一种封装SELECT语句的层次。

存储过程

存储过程:简单来说,存储过程就是为以后使用而保存的一条或者多条SQL语句。可以将其视为批文件,虽然他们的作用不仅限于批处理。

在存储过程的定义中可以定义参数,参数分为IN、OUT、ONOUT三种类型。

  1. IN类型:表示接受调用者传入的数据;
  2. OUT类型:表示向调用者返回数;
  3. INOUT类型:既可以接受调用者传入的参数,也可以向调用者返回数据。

存储过程的特点

  1. 通过处理封装在容易使用的单元中,简化了复杂的操作。
  2. 简化对变动的管理。如表名、列名、或者业务逻辑有了变化。只需要更改存储过程的代码。使用它的人不用修改自己的代码。
  3. 有助于提高应用程序的性能
  4. 减少应用程序与数据库服务器之间的流量。应为应用程序不必发送多个冗长的SQL语句,只用发送存储过程中的名称和参数即可。

缺点:

  1. 大量使用存储过程,这些存储过程的每个链接的内存使用量将大大增加。
  2. 如果在存储过程中大量使用逻辑操作,CPU的使用率也会增加。MySQL数据库最初的设计就侧重于高效的查询,而不是逻辑运算。
CREATEPROCEDURE 数据库名.存储过程名([in变量名 类型,out 参数 2...])BEGIN[DECLARE 变量名 类型 [DEFAULT];]存储过程的语句块;END;

定义一个存储过程:

CREATEPROCEDURE `demo2`(IN s_sex CHAR(1),OUT s_count INT)-- 存储过程体BEGIN-- 把SQL中查询的结果通过INTO赋给变量SELECT COUNT(*) INTO s_count FROM student WHERE sex = s_sex;SELECT s_count;END$$

调用这个存储过程:

-- @s_count表示测试出输出的参数
CALL demo2 ('男',@s_count);
/* 结果
s_count6
*/

触发器

触发器trigger是一种特殊的存储过程,其特殊性在于它并不需要用户直接调用,而是对表添加、修改、删除之前或者之后自动执行的存储过程。

触发器的特点

  1. 与表相关联

    触发器定义在特定的表上,这个表称为触发器表。

  2. 自动激活触发器

    当表中的数据执行INSERT、UPDATE或者DELETE操作时,如果表上的这个操作定义了触发器,该触发器自动执行,这是不可以撤销的。

  3. 不能直接调用

    与存储过程不同,触发器不能被直接调用,也不能传递或者接受参数。

  4. 作为事务的一部分

    触发器和激活触发器的语句一起作为一个单一的事务来对待,可以从触发器中的任何位置回滚。

定义触发器:

CREATE TRIGGER 触发器名称 触发时机 触发事件
ON 表名称FOR EACH ROW -- 行级触发
BEGIN语句
END;

语法解析:

  1. 发器名称:用来标识触发器的,由用户自定义。
  2. 触发时机:其值为before或者after。
  3. 触发事件:insert、update和delete
  4. 表名称:表示在哪张表建立触发器
  5. 语句:触发器程序体,触发程序可以使用begin和end作为开始和结束,中间包含多条语句;

删除用户时,自动删除用户菜单关系

DELIMITER $$
CREATE TRIGGER delete_user_menu BEFORE DELETE
ON t_user
FOR EACH ROW
BEGINDELETE FROM t_user_menu WHERE user_id = old.id;
END$$;

新增用户时 自动向其他表中插入数据

DELIMITER $$
CREATE TRIGGER save_user_log AFTER INSERT
ON user
FOR EACH ROW
BEGININSERT INTO test(id,NAME)VALUES(new.id,new.account);
END$$;

在行级触发器代码中,可以使用old和new访问到该行的旧数据和新数据,old和new是对应表的行记录类型变量。

MySQL引擎

数据库引擎用于存储、处理和保护数据的核心服务。利用数据库引擎可控制访问权限并且快速处理事务,从而满足企业内大多数需要大量数据的应用程序要求。

存储引擎主要有:

MyIsam、InnoDB、Memory、Blackhole等。

mysql数据库默认引擎是InnoDB

InnoDB是一个事务型的存储引擎,有行级锁和外键约束,支持全文检索(索引),它的设计目标是处理大容量数据库系统,MySQL运行时InnoDB会在内存中建立缓冲池,用于缓冲数据和索引;支持主键自增,不存储表的总行数。

索引

为什么要有索引呢?

假设某张表中有10万条数据,这100万条数据在硬盘上是存储在数据页上的,一页数据大小为16K,100万条数据需要很多数据页,现在如果要查询id = 8900条数据信息。MySQL需要全表扫描来找到id = 8900 的数据,也就是从“数据页1”来查询,对于大量数据查询起来是非常慢的。

什么是索引

索引就是一个排好序的快速查找的数据结构。

数据库除存储数据本身之外,还维护着一个满足特定查找算法的数据结构,这些数据结构以某种方式指向数据,这要就可以在这些数据结构的基础上实现高级查找算法,这种数据结构就是索引。

在这里插入图片描述

左边是数据表,一共两列七行记录,最左边表示数据记录的地址,为了加快Col2的查找速度,可以维护一个右边所示的二叉查找树,每个节点分别包含索引键值和一个执行对应数据记录物理地址的指针,这样就可以运用二叉查找在一定的复杂度内获取到响应数据,而快速的检索出符合条件的记录。

索引的原理类似于查字典,查询书籍等。本质都是不断地缩小数据范围筛选出想要的结果。

索引的优势

提高数据检索的效率,降低数据库的IO成本

通过索引列对数据进行排序,降低数据排序的成本,降低了CPU的消耗

索引的劣势

索引也是一张表,该表保存了主键与索引字段,并指向实体表的记录,所以索引列也是要占用磁盘内存的。

索引提高查询速度的同时也会降低更新表的速度,例如进行INSERT、UPDATE和DELETE因为更新时,MySQL不仅要保证数据,还要保证一下,索引文件,每次更新添加了索引列的字段,都会调整因为更新带来的键值变化后的索引信息。

索引类型

FULLTEXT:全文索引,一般用于查找文本中的关键字,而不是直接比较是否相等,多在char、varchar、text 等数据类型中创建全文索引。全文索引主要是用来解决like模糊匹配效率低的问题

HASH:哈希索引,多用于等值查询,时间复杂度为o(1),效率非常高,但是不支持排序、范围查询和模糊查询等

BTREE:B+数索引,InnoDB存储引擎默认的索引,支持排序,分组,范围查询,模糊查询等,并且性能稳定。

RTREE:空间数据索引,多用于地理数据的存储,优势在于支持范围查找。

索引种类

主键索引:设定为主键后数据库会自动创建索引;

ALTER TABLE 表名 add PRIMARY KEY 表名(列名);

单列索引:一个索引值包含一个列,一个表可以有多个单列索引

CREATE INDEX 索引名 ON 表名(列名);

唯一索引:索引列的值必须唯一,允许为null

CREATE UNIQUE INDEX 索引名 ON 表名(列名);

组合索引:一个索引包含多个列,在数据库操作期间,符合索引比单值左印所需要的的开销更小(对于相同的多个列建立索引)

CREATE INDEX 索引名 ON 表名(列 1,列 2…);

组合索引最左前缀原则

例如某个表中有a、b、c三列,a、b为组合索引,那么使用时需要满足最左侧索引原则。在使用组合索引的列作为条件时,必须出现最左侧列作为条件,否则组合索引不生效。

-- 列如
select * from table where a=’’and b=’’-- 索引生效
select * from table where b=’’and a=’’-- 索引生效
select * from table where a=’’and c=’’-- 索引生效
select * from table where b=’’and c=’’-- 索引不生效

索引创建原则

需要创建索引

  • 主键自动创建唯一索引
  • 频繁作为查询条件的字段应该设置为索引,就是where后面的语句
  • 查询中与其他表关联的字段,外键关系建立索引
  • 查询中排序的字段,排序字段若通过索引去访问将大大提高排序速度
  • 分组中的字段需要建立索引

不要创建索引

  • 表记录太少

  • 经常增删改的表:索引提高了查询的速度,同时会降低更新表的速度,如对表进行INSERT、UPDATE、DELETE,因为更新表时,MySQL不仅要存储数据,还要更新索引文件

  • where条件里用不到的字段不创建索引

  • 数据重复且分布平均的表字段

B树和B+树的区别

数据库为什么使用B+树而不是B树

聚簇索引和非聚簇索引

聚簇索引

找到了索引就找到了需要的数据,那么这个索引就是聚簇索引,所以主键就是聚簇索引。

非聚簇索引

索引的存储和数据是分离的,也就是说找到了索引但是没有找到数据,需要根据索引上的值再次回表查询,非聚簇索引也叫辅助索引。

一个例子

CREATE TABLE student (id BIGINT,NO VARCHAR (20), NAME VARCHAR (20), PRIMARY KEY (`id`), UNIQUE KEY `idx_no` (`no`)
)

创建一个学生表,做三种查询:

SELECT * FROM student WHERE id = 1

直接根据主键查询获取所有字段数据,此时主键是聚簇索引,因为主键对应的索引叶子节点存储了id=1的所有字段的值。

SELECT NO,NAME FROM student WHERE NO = 123

根据编号查询,编号本身是一个唯一索引,但查询的列包含学生编号和学生姓名,当命中编号索引时,该索引的节点的数据存储的是主键ID,需要根据主键ID重新查询一次,所以这种查询下编号no不是聚簇索引。

SELECT NO FROM student WHERE NO = 123

根据编号查询编号,?这有啥好差的?要的。可能是验证数据库中是否存在该编号,这种查询命中编号索引时,直接返回编号,因为需要的数据就是该索引,不需要回查,这种场景下no就是聚簇索引。

数据库事务

MySQL事务处理主要有两种方法

  1. 用BEGIN、ROLLBACK、COMMIT来实现

    BEGIN:开启一个事务

    ROLLBACK:事务回滚

    COMMIT:事务确认

  2. 直接用set来改变MySQL的自动提交模式:

    set global autocommit = 0;-- 禁止自动提交set global autocommit = 1;-- 开启自动提交
    

查看autocommit模式:

show global variables like 'autocommit';

事务隔离级别

为什么要有隔离级别?

MySQL是一个服务器/客户端软件架构,也就是说,多个客户端连接服务器后,可以同时在不同的会话(一个客户端与服务器连接成功后就叫一个会话)中对服务器进行操作,输入各种语句,这些语句可以作为事务的一部分进行处理。不同的会话可以同时发送请求,也就是说服务器可能同时在处理多个事务,这样可能会导致不同的事务同时访问相同的数据。因为一个事务具有隔离性,当一个事务提交后其他事务才能执行继续访问这个数据。这样对性能影响很大,所以设计数据库时就提出来各种隔离级别,来最大限度的提升系统并发处理事务的能力。

查看隔离级别

SELECT @@global.transaction_isolation,@@transaction_isolation;

mysql数据库提供了四种隔离级别,实际开发根据不同场景选择不容的隔离级别,除了串行化其他级别都存在某种问题。

SET GLOBAL TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

原数据users表:

idnameage
1jim20

设置隔离级别为未提交读(read uncommitted):

同时开启两事务A、B,B事务在A事务还没有提交的时候读取A中修改的数据。

事务A:

BEGIN;UPDATE users SET age = 18 WHERE id = 1 -- 1ROLLBACK -- 3COMMIT; -- 4

事务B:

BEGIN;SELECT age FROM users WHERE id = 1 -- 2COMMIT;-- 5
/*
结果: 18
数据库表 age = 20
*/

B读取可A未提交的数据,A事务中发生了回滚,数据库中age并没有被修改,所以B事务读取到的数据是错的,所以称之为脏读

设置提交读隔离级别(read committed):

同时开启两个事务A、B,B事务在A事务提交后才能读取到A中修改的结果。

A事务未提交时,B事务获取到的仍然是事务开启前的结果。

A事务:

SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED
BEGIN;UPDATE users SET age = 18 WHERE id = 1-- 1COMMIT;-- 3

B 事务:

SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED
BEGIN;SELECT age FROM users WHERE id = 1 -- 2  结果 20SELECT age FROM users WHERE id = 1 -- 4 结果 18COMMIT;-- 5

提交读隔离级别可以解决脏读问题,但是B事务中两次查询的结果不一致,称为不可重复读

设置可重复读隔离级别(repeatable read):

MySQL默认的隔离级别。同一个事务中多次读取相同的数据返回的结果是一样的。其避免了脏读和不可重复读问题,但是除InnoDB 外幻读依然存在。

事务A:

SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READBEGIN;UPDATE users SET age = 18 WHERE id = 1 -- 2COMMIT; -- 3 

事务B:

SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READBEGIN;SELECT age FROM users WHERE id = 1 -- 1 结果18SELECT age FROM users WHERE id = 1 -- 4 结果18COMMIT; -- 4

可重复读,可能会产生幻读问题,幻读就是B事务查询了users 表,发现只有id=1的用户想要添加一个id = 2的用户,但是A事务快一步添加,B事务在添加的时候就会显示重复的主键,可是B事务查询明明没有id = 2的数据。

设置串行化(serializable)

SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE

解决幻读问题:

读写加锁,B事务如果未提交,A事务是无法insert的,必须等待B事务提交;

事务A:

SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLEBEGIN;INSERT INTO users(id,NAME,age) VALUE (3 ,"ldl",18)-- 2 执行后一直在等待状态,直到B事务提交.COMMIT;

事务B:

SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN;SELECT * FROM users  -- 1COMMIT;
事务隔离级别脏读不可重复读幻读
read uncommitted可能可能可能
read committed不可能可能可能
repeatable read不可能不可能可能
serializable不可能不可能不可能

事务实现的原理

MySQL中日志有很多种,如二进制日志、错误日志、查询日志、慢查询日志等,此外InnoDB存储引擎还提供了两种日志,redolog(重做日志)和undolog(回滚日志)。其中redolog用于保存事务的持久性;undolog则是事务原子性和隔离性实现的基础。

在这里插入图片描述

原子性实现原理

原子性实现的关键,是当事务发生回滚的时候,能撤销所有已经成功执行的SQL语句。InnoDB实现回滚靠的是undolog:当事务对数据库中的数据进行修改时,InnoDB会生成对应的undolog;如果事务执行失败或者是执行ROLLBACK,导致事务需要回滚时,就可以利用undolog中的数据来回滚到修改之前的样子。

undolog属于逻辑日志,它记录的是SQL执行的相关信息。当发生回滚时,InnoDB会根据undolog的内容做与之前相反的工作:对于每个insert,回滚时执行delete,每个delete执行insert,每个update执行一个相反的update,把数据改回去。

持久性实现原理

redolog叫做重做日志,是保证实物持久性的重要机制。当mysql服务器意外崩溃或者宕机后,保证已经提交的事务,确定持久化到磁盘中的一种措施。

InnoDB是以页为单位来管理存储空间的,任何的增删改查操作最终都会操作完整的一个页,会将整页的数据加载到buffer pool中,然后对需要修改的记录进行修改,修改完毕后不会立即刷新到磁盘中,而且仅仅修改了一条记录,刷新一个完整的数据页的话过于浪费了。但是如果不刷新的话,数据此时还在内存中,如果此时系统崩溃最终数据会丢失。因此引入了redolog,也就是说,修改完成之后不立即刷新,而是记录一条日志,日志内容就是记录那个页面,多少偏移量,什么数据发生了什么改变。这样即使系统崩溃,在恢复后也可以根据日志进行数据恢复。另外,redolog是循环写入固定的文件,是顺序写入磁盘的。

总结:redolog就是记录在操作之后,记录哪个页面,多少偏移量,什么数据发生了怎样的变化。

隔离级别实现原理MVCC

MVCC是什么?

多版本并发控制(MVCC,Multi-Version Concurrent Control),是MySQL提高性能的一种方式,配合undolog和版本链,让不同事务的读写、写读操作可以并发执行,减少锁的使用,从而提升系统的性能。

MVCC的目的是让读写,写读操作并发执行.

MVCC使得数据库读不会对数据加锁,普通的select请求不会加锁,提高了数据库的并发处理能力。借助MVCC,数据库可以实现READ COMMITTED,REPEATABLE READ等隔离级别。

在这里插入图片描述

事务D的两次查询在不同的隔离级别结果是不同的。

读未提交:name = 张二三 ;name = 张三三

读已提交:name = 张三 ;name = 张二三

可重复读: name = 张三; name = 张三

MVCC是通过在每行记录后面保存两个隐藏的列来实现的。一个保存行的事务ID(TRX_ID),一个保存了行的回滚指ROLL_PT).

trx_id:每次对某行记录执行改动时,都会把对应事务id赋值给trx——id隐藏列。

roll_pt:每次对记录进行改动时,都会把旧版本写到undolog日志中,然后这个隐藏列就相当于一个指针,可以通过它来找到修改前的信息。
在这里插入图片描述

对该记录每次更新后,都会将旧值放到一条 undolog 中,就算是该记录的一个旧版本,随着更新次数的增多,所有的版本都会被 roll_pt 属性连接成一个链表,我们把这个链表称之为版本链,版本链的头节点就是当前记录最新的值。另外,每个版本中还包含生成该版本时对应的事务 id,这个信息很重要。

ReadView 是什么

ReadView是“快照读”SQL执行时MVCC提取数据的依据,是一个数据结构,包含4个字段

m_ids:当前活跃的事务编号集合

min_trx_id:最小活跃事务编号

max_trx_id:预分配事务编号,当前最大事务编号+1

creator_trx_id:ReadView创建者的事务编号

读已提交(RC):

在这里插入图片描述
在这里插入图片描述

可重复读(RR):
在这里插入图片描述

读已提交级别: 称为当前读,当每个事物每次读取时,会生成一个 readVew,读取

的是最新数据.

可重复读级别: 称为快照读,当一个事务第一次查询时,会生成一个 readView,第二次查询时仍会从当前 readView 中读数据.

锁机制

行锁、间隙锁、表锁

按照粒度,锁可以分为行锁、间隙锁和表锁。间隙锁位于行锁和表锁之间。表锁在操作数据时会锁定整张表,并发性能差;行锁只锁定需要操作的数据,并发性能好,但是加锁本身就需要消耗资源(获取锁、检查锁、释放锁等都需要耗费资源),因此在锁定数据较多情况下使用表锁可以节省大量资源。MySQL中不同存储引擎支持的锁是不一样的,MyIsam支持表锁,InnoDB同时支持表锁和行锁。

行锁

MySQL中粒度最小的一种锁,表示只针对当前操作的行进行加锁。行锁能大大减少数据库操作的冲突。其锁的粒度小,但是加锁的开销大

特点:开销大;加锁慢;会出现死锁;锁定力度小,发生冲突概率低;并发度也高。

间隙锁

锁的是一个区间,当我们用范围条件而不是相等条件检索数据,InnoDB 会给符合条件的已有数据记录的索引项加锁;对于键值在条件范围内但并不存在的记录,叫做“间隙",InnoDB 也会对这个“间隙”加锁,这种锁机制就是所谓的间隙锁(Next-Key 锁)。 例如:

select * from student where id>2 and id<5
/*
数据库中只有id为1和2的数据
即使数据库中没哟id = 3 的数据,其他线程想要添加id为3的数据也是不可以的,因为2到5的数据已经被锁定.
*/

表锁

表级锁是 MySQL 中锁定粒度最大的一种锁,表示对当前操作的整张表加锁,它实现简单,资源消耗较少,被大部分 MySQL 引擎支持。最常使用的MYISAM 与 INNODB 都支持表级锁定。表级锁定分为表共享锁与表排他锁。

特点:

开销小,加锁快;不会出现死锁;锁定粒度大,发出锁冲突的概率最高,并发度最低.

共享锁(s)

共享锁又称为读锁。允许一个事务去读一行,组织其他事务获取相同数据的排他锁。若事务T对数据A加上S锁,则事务T可以读取A但是不能修改A,其他事务只能对A加S锁,不能加X锁,直到T释放A上的S锁。

排他锁(X)

排他锁又称为写锁。允许获取排他锁的事务更新数据,阻止其他事务取得相同的数据集共享读锁和排他写锁。若事务 T 对数据对象 A 加上 X 锁,事务 T可以读 A 也可以修改 A,其他事务不能再对 A 加任何锁,直到 T 释放 A 上的锁。update,delete,insert 都会自动给涉及到的数据加上排他锁,select 语句默认不会加任何锁类型。

SQL优化

  1. 尽量不要使用select * ,而是使用具体字段。可能用到覆盖索引,减少回表,提高查询效率。

  2. 避免在where字句中使用or来链接条件,使用union all吧两个SQL结果合并。使用or可能会使索引失效,从而全表扫描。

  3. 尽量用数值代替字符串类型。如:主键用int类型,性别用0/1.在查询和链接时会逐个比较字符串的每个字符;数值类型只需要比较一次就可以了。

  4. 对于查询的优化,尽量避免全表扫描,首先应该考虑在where以及order by涉及到的列上建立索引

  5. 尽量避免索引失效
    5.1 在where字句中对字段进行null值判断,否则将会导致引擎放弃使用索引进而全表扫描,可以在num上设置默认值0,

    5.2 避免在where字句中使用or来链接条件,将会导致引擎无法使用索引进而全表扫描,使用union all吧两个SQL结果合并。

    5.3 in和not in 也要谨慎使用,例如in(1,2,3)这种连续的数值,能用between就不要用in,between 1 and 3

    5.4 模糊查询也将导致全表扫描。

    5.5尽量避免在where字句中对字段进行函数操作,这将导致引擎放弃使用索引而进行全表扫描。如:: select id from t where substring(name,1,3)='abc

  6. inner join、left join、right join优先使用inner join

    三种连接如果结果相同,优先使用 inner join

    inner join 内连接,只保留两张表中完全匹配的结果集;

    left join 会返回左表所有的行,即使在右表中没有匹配的记录;

    right join 会返回右表所有的行,即使在左表中没有匹配的记录;

  7. 使用group by 时,建议先过滤在分组

  8. 清空表时,优先使用truncate

    truncate table 比 delete 速度快,且使用的系统和事务日志资源少.

    delete 语句每次删除一行,并在事务日志中为所删除的每行记录一项。truncate

    table 通过释放存储表数据所用的数据页来删除数据.

  9. 表链接不宜太多

  10. 不建议在索引上使用内置函数

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/33708.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Android Https

本质&#xff1a;在客户端和服务端使用非对称加密协商出一套对称密钥&#xff0c;每次发送数据前加密&#xff0c;收到后解密&#xff0c;达到加密传输 http ssl 在http之下增加了安全层&#xff0c;用于保障http的加密传输 HTTPS连接 TLS连接步骤 1.客户端发送 client h…

【Linux】网络基础2

文章目录 网络基础21. 应用层1.1 协议1.2 HTTP 协议1.2.1 URL1.2.2 urlencode和urldecode1.2.3 HTTP协议格式1.2.4 HTTP的方法1.2.5 HTTP的状态码1.2.6 HTTP 常见的header1.2.7 最简单的HTTP服务器 2. 传输层2.1 端口号2.1.1 端口号范围划分2.1.2 认识知名端口号2.1.3 netstat2…

Redis_安装、启动以及基本命令

2.Redis安装 2.1前置处理环境 VMware安装安装centOS的linux操作系统xshellxftp 2.2 配置虚拟机网络 按ctrlaltf2 切换到命令行 cd (/)目录 修改/etc/sysconfig/network-scripts/ifcfg-ens3 vi 命令 按insert表示插入 按ctrlesc退出修改状态 :wq 写入并退出 此文件必须保持一…

10.pod资源限制和健康检查

文章目录 资源限制探针&#xff08;健康检查&#xff09;启动、退出动作总结 资源限制 当定义 Pod 时可以选择性地为每个容器设定所需要的资源数量。 最常见的可设定资源是 CPU 和内存大小&#xff0c;以及其他类型的资源。当为 pod 中的容器指定了 request 资源时&#xff0c…

Redis_持久化(AOF、RDB)

6. Redis AOF 6.1 简介 目前&#xff0c;redis的持久化主要应用AOF&#xff08;Append Only File&#xff09;和RDF两大机制&#xff0c;AOF以日志的形式来记录每个写操作&#xff08;增量保存&#xff09;&#xff0c;将redis执行过的所有指令全部安全记录下来&#xff08;读…

C语言一些有趣的冷门知识

文章目录 概要1.访问数组元素的方法运行结果 2.中括号的特殊用法运行结果 3.大括号的特殊用法运行结果 4.sizeof的用法运行结果 5.渐进运算符运行结果 小结 概要 本文章只是介绍一些有趣的C语言知识&#xff0c;纯属娱乐。这里所有的演示代码我是使用的编译器是Visual Studio …

入门指南 | 如何系统搭建自己的营销战略学习体系成为领域专家?

独自进入一个行业&#xff0c;如果你没有几年的行业经验或者独特的营销方式&#xff0c;很难在行业里站住脚&#xff08;每个行业潜规则都很多&#xff09;。 每个行业都有周期&#xff0c;都有很多竞争对手&#xff0c;你扎进去一个具体的行业&#xff0c;对于各种资源有限的自…

uni-app实现图片上传功能

效果 代码 <uni-forms-item name"ViolationImg" label"三违照片 :"><uni-file-picker ref"image" limit"1" title"" fileMediatype"image" :listStyles"listStyles" :value"filePathsL…

企业举办活动邀请媒体的意义和重要性

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 企业举办活动并邀请媒体的意义和重要性是多方面的&#xff0c;主要有以下一些&#xff1a; 1. 品牌曝光与宣传&#xff1a;邀请媒体参与企业活动可以提高企业的品牌曝光度。媒体报道能够…

kubernetes的存储卷使用

目录 一、为什么使用存储卷 二、emptyDir存储卷 1.概念 2.创建Pod emptyDir 3. 验证emptyDir存储卷 三、hostPath存储卷 1.概念 2.创建Pod hostPath 3.验证hostPath存储卷 三、nfs共享存储卷 1.概念 2.安装nfs&#xff0c;配置nfs服务 3.创建Pod 4.验证nfs存储卷 一、…

论文笔记--Llama 2: Open Foundation and Fine-Tuned Chat Models

论文笔记--Llama 2: Open Foundation and Fine-Tuned Chat Models 1. 文章简介2. 文章概括3 文章重点技术3.1 预训练Pretraining3.1.1 预训练细节3.1.2 Llama2模型评估 3.2 微调Fine-tuning3.2.1 Supervised Fine-Tuning(FT)3.2.2 Reinforcement Learning with Human Feedback(…

(二)结构型模式:2、桥接模式(Bridge Pattern)(C++实现示例)

目录 1、桥接模式&#xff08;Bridge Pattern&#xff09;含义 2、桥接模式应用场景 3、桥接模式的UML图学习 4、C实现桥接模式的示例 1、桥接模式&#xff08;Bridge Pattern&#xff09;含义 桥接模式是一种结构型设计模式&#xff0c;它将抽象部分与实现部分分离&#…

构建Docker容器监控系统(Cadvisor +Prometheus+Grafana)

Cadvisor PrometheusGrafana 1.1、Cadvisor产品简介 Cadvisor是Google开源的一款用于展示和分析容器运行状态的可视化工具。通过在主机上运行Cadvisor用户可以轻松的获取到当前主机上容器的运行统计信息&#xff0c;并以图表的形式向用户展示。 1.2、安装docker-ce [rootloc…

arcgis栅格数据之最佳路径分析

1、打开arcmap&#xff0c;加载数据&#xff0c;需要对影像进行监督分类&#xff0c;如下&#xff1a; 这里任选一种监督分类的方法&#xff08;最大似然法&#xff09;&#xff0c;如下&#xff1a; 这里会先生成一个.ecd文件&#xff0c;然后再利用.ecd文件对影像进行分类。如…

rust关于项目结构包,Crate和mod和目录的组织

rust 最近开始学习rust语言。感觉这门语言相对java确实是难上很多。开几个文章把遇到的问题记录一下 rust关于包&#xff0c;Crate 关于包&#xff0c;Crate这块先看看官方书籍怎么说的 crate 是 Rust 在编译时最小的代码单位。如果你用 rustc 而不是 cargo 来编译一个文件…

阿里云服务器安装部署Docker使用教程

本文阿里云百科分享如何在云服务ECS实例上&#xff0c;部署并使用Docker。Docker是一款开源的应用容器引擎&#xff0c;具有可移植性、可扩展性、高安全性和可管理性等优势。开发者可将应用程序和依赖项打包到一个可移植的容器中&#xff0c;快速发布到Linux机器上并实现虚拟化…

selenium常见等待机制及其特点和使用方法

目录 1、强制等待 2、隐式等待 3、显示等待 1、强制等待 强制等待是在程序中直接调用Thread.sleep(timeout) ,来完成的&#xff0c;该用法的优点是使用起来方便&#xff0c;语法也比较简单&#xff0c;缺点就是需要强制等待固定的时间&#xff0c;可能会造成测试的时间过…

【数据结构】链表(一)

链表&#xff08;一&#xff09; 文章目录 链表&#xff08;一&#xff09;01 引入02 概念及结构03 单向不带头不循环链表实现3.1 创建节点类型3.2 简易创建一个链表3.3 遍历链表每个节点3.4 获取链表长度3.5 查找是否包含关键字key是否在单链表当中3.6 头插法3.7 尾插法3.8 任…

JVM之内存模型

1. Java内存模型 很多人将Java 内存结构与java 内存模型傻傻分不清&#xff0c;java 内存模型是 Java Memory Model&#xff08;JMM&#xff09;的意思。 简单的说&#xff0c;JMM 定义了一套在多线程读写共享数据时&#xff08;成员变量、数组&#xff09;时&#xff0c;对数据…

2023-08-08 Ubuntu 挂载U盘 fdisk -l 、sudo mount /dev/sdb1 /mnt/mydisk

一、基本命令 1、插入U盘&#xff0c;查看U盘是否被系统识别&#xff1a; 打开终端&#xff0c;输入&#xff1a; sudo fdisk -l 查看系统是否识别U盘&#xff0c;如果识别&#xff0c;会显示U盘的相关信息&#xff0c;如果没有识别&#xff0c;则说明系统没有识别U盘。 2…