笛卡尔积:两个集合A集合和B集合的所有组合情况(在多表查询时,需要消除无效的笛卡尔积)消除无效笛卡尔积:
inner join显式内连接是hashtable连接比较 ,O(Log N)例子:
where隐式内连接是取笛卡尔积过滤,O(N**2)
特别注意点:SQL在使用in()的时候要注意,括号内一定要有数据,如果没有数据或者null则会报错SQL语法错误例子:
这三个问题的详细演示:https://www.bilibili.com/video/BV1Kr4y1i7ru?p=55cd并发事务隔离级别:
不同引擎之间主要的区别为:事务、行级锁、外键特点InnoDBMyISAMMemory存储限制64TB有有事务安全支持--锁机制行锁表锁表锁B+tree索引支持支持支持Hash索引--支持全文索引支持(5.6版本之后)支持-空间使用高低N/A内存使用高低中等批量插入速度低高高支持外键支持--
-- session 是查看当前会话 ;SHOW GLOBAL STATUS LIKE 'Com_______'; 或者 SHOW SESSION STATUS LIKE 'Com_______';
-- global 是查询全局数据 ;
聚集索引查询是const,二级索引查询是ref,不用索引查询是all(全表扫描)
B-Tree 的数据插入过程动画参照:https://www.bilibili.com/video/BV1Kr4y1i7ru?p=68
演示地址:https://www.cs.usfca.edu/~galles/visualization/BTree.html
注意:页与页之间是双向链表,页内是单项链表。
以下图为例:6和12之间应是单向链表;6 12 和16 18 之间应是双向链表
演示地址:https://www.cs.usfca.edu/~galles/visualization/BPlusTree.html与 B-Tree 的区别:
注意:页与页之间是双向链表,页内是单项链表。
以下图为例:6和12之间应是单向链表;6 12 和16 18 之间应是双向链表
这里的运算操作包含:函数、类型转换等
SQL提示就是指定索引是优化数据库的一个重要手段,简单来说,就是在SQL语句中加入一些人为的提示来达到优化操作的目的。
省流版:
- 插入数据:① insert: 批量插入、手动控制事务、主键顺序插入 ②大批量插入: load data local infile
- 主键优化:主键长度尽量短,如:自增AUTO INCREMENT,少用UUID、雪花算法等
- order by 优化:① using index:直接通过联合索引返回数据,性能高;② using filesort:需要将返回的结果在排序缓冲区排序
- group by 优化:联合索引,多字段分组满足最左前缀法则
- limit 优化:覆盖索引 + 子查询
- count()优化:性能考虑,count(字段)< count(主键 id) < count(1)约等于 count(*)
- update 优化:尽量根据主键/索引字段进行数据更新
mysql默认是每次操作都会提交一次事务,这样很消耗数据库性能,要改成多次操作一次性提交
就是按照id:1,2,3,4,5插入比id:5,0,9,1,36,2插入效率高
本地文件只需要有一定规则就可以直接加载进数据库表中。使用load指令的操作:
如:1,conan,男,180,120 几个字段就几个数据对应,中间用逗号/分号/句号等统一符号即可
主键设计原则:数据组织方式:在InnoDB存储引擎中,表数据都是根据主键顺序组织存放的,这种存储方式的表称为索引组织表(Index organized table, IOT)
- 满足业务需求的情况下,尽量降低主键的长度(二级索引的叶子节点保存的就是主键,所以主键小占用的空间也就会少)
- 插入数据时,尽量选择顺序插入,选择使用 AUTO_INCREMENT 自增主键
- 尽量不要使用 UUID、雪花算法 做主键或者是其他的自然主键,如身份证号,占用的空间大。
- 业务操作时,避免对主键的修改
总结:
- 根据排序字段建立合适的索引,多字段排序时,也遵循最左前缀法则
- 尽量使用覆盖索引(覆盖索引是指查询时查字段且字段是索引中的,联合索引是指多个字段一起绑定为一个索引)
- 多字段排序,一个升序一个降序,此时需要注意联合索引在创建时的规则(ASC/DESC)
- 如果不可避免出现filesort,大数据量排序时,可以适当增大排序缓冲区大小 sort_buffer_size(默认256k)
若对视图进行增数据操作是可以插入的,且插入到关联的表中视图(View)是一种虚拟存在的表。视图中的数据并不在数据库中实际存在,行和列数据来自定义视图的查询中使用的表,并且是在使用视图时动态生成的。
存储过程和存储函数的区别:存储过程更多用来封装脚本(执行一些重复性操作),存储函数更多是封装一个简单的方法(查询操作)不能修改表数据。语法结构:
- 返回值:存储过程可以不返回值、返回多个结果集,而存储函数必须返回一个值
- 调用语法:调用存储过程使用CALL语句,而调用存储函数使用SELECT语句
以下的互斥是说事务还没提交之前,其他事务无法提交锁是计算机协调多个进程或线程并发访问某一资源的机制。在数据库中,除传统的计算资源(CPU、RAM、I/O)的争用以外,数据也是一种供许多用户共享的资源。如何保证数据并发访问的一致性、有效性是所有数据库必须解决的一个问题,锁冲突也是影响数据库并发访问性能的一个重要因素。从这个角度来说,锁对数据库而言显得尤其重要,也更加复杂。
以下语句是查看意向锁和行锁的加锁情况:
select object_schema,object_name,index_name,lock_type,lock_mode,lock_data from performance_schema.data_locks;
读锁不会阻塞其他客户端的读,但是会阻塞写。写锁既会阻塞其他客户端的读,又会阻塞其他客户端的写。
前置知识:每次增删改都是将操作先放入Buffer Pool和redolog buffer中,然后再写入磁盘。
个人理解: 事物每次提交的时候都会将数据刷到redo log中而不是直接将buffer pool中的数据直接刷到磁盘中(ibd文件中),是因为redo log 是顺序写,性能处理的够快,而Buffer Pool直接刷到ibd中,是随机写,性能慢。所以脏页是在下一次读的时候,或者后台线程采用一定的机制进行刷盘到ibd中。
最新个人理解:当Buffer Pool可以正常同步到磁盘文件时,就不用redolog日志。但假如Buffer Pool写入磁盘时发生错误(宕机),就会通过Redolog buffer将未同步的脏数据同步到磁盘。
注意:
- 磁盘中redolog日志ibd会定期删除掉,因为他们只用保证短期(宕机期间)的数据操作能够持久化就行。
- 磁盘中的redolog日志ibd是有两份的,循环写。
Undo log销毁:undo log在事务执行时产生,事务提交时,并不会立即删除undo log,因为这些日志可能还用于MVCC。自己Process on上的总结
Undo log存储:undo log采用段的方式进行管理和记录,存放在前面介绍的rollback segment回滚段中,内部包含1024个undo log segment。
redo log:记录的是数据页的物理变化,服务宕机可用来同步数据。答:
undo log:记录的是逻辑日志,当事务滚时,通过逆操作恢复原来的数据。
区别:redo log保证了事务的持久性,undolog保证了事务的原子性和一致性
这个原理去看自己的process on 上的思维导图:全称Multi-Version Concurrency Control,多版本并发控制。指维护一个数据的多个版本,使得读写操作没有冲突,快照读为MySQL实现MVCC提供了一个非阻塞读功能。MVCC的具体实现,还需要依赖于数据库记录中的三个隐式字段、undo log日志、readView。
undo log回滚日志,在insert、update、delete的时候产生的便于数据回滚的日志。undo log 版本链:
当insert的时候,产生的undo log日志只在回滚时需要,在事务提交后,可被立即删除。
而update、delete的时候,产生的undo log日志不仅在回滚时需要,在快照读时也需要,不会立即被删除。
RC隔离级别下,在事务中每一次执行快照读时生成ReadView。
RR隔离级别下,在事务中第一次执行快照读时生成ReadView,后续会复用。
https://www.bilibili.com/video/BV1Kr4y1i7ru?p=145&spm_id_from=pageDriver&vd_source=bbc04b831b54029788a178a7c2e9ae20MVCC 靠 隐藏字段 , undo log 版本链 , read view 实现的。
欢迎光临 IT评测·应用市场-qidao123.com (https://dis.qidao123.com/) | Powered by Discuz! X3.4 |