免费流程图制作网站,门户网站建设 简报,东莞房价2022,辽宁工业大学教务管理系统1 聚簇索引
1 和主键索引的关系 2 和非聚簇索引的关系#xff0c;其叶子节点存储的是聚簇索引中的主键 3 索引覆盖机制使得非聚簇索引不用回表二次查询
2 举一个使用索引覆盖的例子
我的项目中没有使用到覆盖索引#xff0c;但是可以举一个例子#xff0c;比如我直接为年…1 聚簇索引
1 和主键索引的关系 2 和非聚簇索引的关系其叶子节点存储的是聚簇索引中的主键 3 索引覆盖机制使得非聚簇索引不用回表二次查询
2 举一个使用索引覆盖的例子
我的项目中没有使用到覆盖索引但是可以举一个例子比如我直接为年龄建立覆盖索引现在我查询年龄为21的人查到了叶子节点后就可以直接取到这些记录而不是像非覆盖索引时查找到主键再去聚簇索引中取得数据
3 范围查询是怎么实现的
B树的所有叶子节点都是双向链表连接起来的查找到左边第一个叶子节点然后依次向右查询直至范围右端点就行。因为链表链接起来的本身是有序的
4 索引失效
4.1 索引失效的情况
1 组合索引使用不当会导致索引失效 2 使用 !这种情况会失效
真实情况
数据库索引可以提高查询效率但在一些情况下索引可能会失效也就是无法使用。以下是一些常见的索引失效的情况使用了不等于、NOT、IS NULL、、、! 操作符的查询语句数据库无法使用索引进行优化。对于组合索引如果查询条件不包含索引的最左侧部分索引可能无法使用。比如有一个包含(a,b,c)的组合索引查询条件只有b或者c的话索引就不能被利用。在列上使用函数或者表达式时索引无法使用。例如 SELECT * FROM table WHERE YEAR(column) 2023;这样的查询无法使用索引。当使用 LIKE 操作符进行模糊查询时如果通配符在前面例如 LIKE ‘%xx’那么索引无法使用。如果通配符在后面例如 LIKE ‘xx%’那么索引仍然可以使用。当OR操作符连接的条件分别在不同的索引列时索引无法使用。如果数据类型不一致比如将字符串类型的列与数字类型进行比较这样的查询也无法使用索引。如果MySQL估计全表扫描比使用索引更快时比如在非常小的表中MySQL也不会使用索引。
4.2 分别讲讲各个失效的点的原因
因为查询的条件是不在索引树的节点中无法匹配也就查找不到具体的主键或者记录自然就失效了 使用了不等于、NOT、IS NULL、、、! 操作符的查询语句数据库无法使用索引进行优化。 数据库索引比如常见的B树索引是基于值的有序排列的当你使用等于或者在IN操作符时数据库能通过索引直接找到对应的值。但如果你使用了不等于或者NOT等操作符数据库需要检查索引中的每一个项来确定哪些值不满足条件性能上等同于全表扫描这就失去了使用索引的意义。至于 “” 或 “” 操作符如果它们作用在范围较大时索引优化的效果也会大大降低。 对于组合索引如果查询条件不包含索引的最左侧部分索引可能无法使用。 对于组合索引比如 (a, b, c)数据库在建立索引时会首先对a进行排序然后在a的值相同的情况下对b进行排序以此类推。如果查询条件不包含索引的最左侧部分数据库就无法有效地利用索引进行查找。 在列上使用函数或者表达式时索引无法使用。 如果你在查询条件中对一个列应用了函数或者表达式数据库就无法直接使用索引找到对应的值而需要对每一个值应用同样的函数或者表达式然后利用表达式的返回值再进行比较因为返回值大多不是主键或者索引字段比如count(),sum()函数这就无法利用索引的优势了。 当使用 LIKE 操作符进行模糊查询时如果通配符在前面例如 LIKE ‘%xx’那么索引无法使用。 基于B树的索引是按照列的值的顺序建立的当你使用LIKE xx%这样的查询时数据库可以直接定位到以’xx’开头的部分然后返回所有符合条件的值。但如果通配符在前面数据库则需要检查所有的值来找出符合条件的部分这样索引就无法发挥作用了这跟使用字段导致索引失效的原因是一样的。 当OR操作符连接的条件分别在不同的索引列时索引无法使用。 这是因为当OR操作符连接的条件分别在不同的索引列时数据库无法同时在两个索引列上进行查找这样就无法利用索引了。 如果数据类型不一致比如将字符串类型的列与数字类型进行比较这样的查询也无法使用索引。 数据库在建立索引时会按照列的数据类型来排序如果查询条件中的数据类型与列的数据类型不匹配那么数据库就无法正确地使用索引了。 如果MySQL估计全表扫描比使用索引更快时比如在非常小的表中MySQL也不会使用索引。 对于非常小的表全表扫描的代价可能比通过索引查找的代价更低。在这种情况下数据库可能会选择全表扫描而不是使用索引。这是因为索引虽然能提高查找速度但它也需要额外的存储空间并且在插入和删除时需要额外的时间来更新索引。因此如果表的大小很小使用索引的代价可能会大于它的收益。
5 讲讲索引下推
索引下推Index Condition PushdownICP是MySQL 5.6版本以后引入的一种优化策略用于提高带有复杂WHERE子句的查询性能。
在没有ICP的情况下MySQL服务器会从存储引擎检索完整的行数据然后在服务器层面对WHERE子句中的条件进行评估。这意味着存储引擎可能会检索出大量最终不满足查询条件的行。 然而当开启ICP特性后一部分的WHERE子句条件会被下推到存储引擎层面。在存储引擎进行索引查找的时候就可以及早地过滤掉不满足这些条件的索引项避免了无用的行数据检索。这对于某些查询可以带来明显的性能提升。
注意不是所有的查询都可以从ICP中受益。MySQL优化器会根据查询的具体情况决定是否使用ICP。而且目前ICP特性只有在InnoDB和MyISAM存储引擎中被支持。
6 事务
6.1 说一下事务的ACID和隔离级别
1 讲解了AID三个特性都是为了C一致性服务的。一般数据库需要使用事务保证数据库的一致性。 正确情况下最好详细讲讲 ACID是用来描述数据库事务的四个关键特性的首字母缩写具体包括
原子性Atomicity一个事务transaction必须被视为一个不可分割的最小工作单元整个事务的所有操作要么全部提交成功要么全部失败回滚对于一个事务来说不能只执行其中的一部分操作。一致性Consistency事务应确保数据库从一个一致的状态转变为另一个一致的状态。一致性是指数据库应满足预定的约束条件如数据的完整性约束等。隔离性Isolation多个并发事务之间需要隔离以防止数据损坏。隔离性保证了一个事务在执行过程中其操作和产生的中间态对其他并发事务是隔离的即一个事务的执行不应影响其他事务。持久性Durability一旦事务提交对数据的修改就是永久性的。即使出现系统故障修改的数据也不会丢失。 这四个特性是数据库事务所必需的可以确保数据的一致性和可靠性。A、I、D三个特性可以看作是为了实现C一致性服务的。事务就是为了保证操作数据库的完整性和一致性这就是ACID的重要性。
2 在SQL标准中定义了四种隔离级别分别是.。。。
6.2 假设第一个线程开启了一个事务在开始和快结束时分别读取一次但是中间第二个线程修改了其中的数据这个时候 第一个线程第二次读取到的数据是线程二修改后的还是修改前的数据?重要
答这个问题的答案取决于你的数据库事务的隔离级别。
如果线程二的事务没有提交在读未提交的隔离级别时可以读取到数据但是在读已提交、RR的级别下都不能读取到线程二修改后的数据都只能读取到修改前的数据。
如果线程二的事务提交了此时不存在读未提交的数据问题但是在读已提交的隔离级别时可以读取到修改后的数据但是在RR级别下读取的是修改前的数据。
Serializable级别下所有事务串行化执行如果第一个线程的事务先执行则全程只能读取到修改前的数据等它执行完了线程二才能继续执行后续的修改操作。
也可以结合下面这个总结看一下
Read Uncommitted未提交读在这个级别一个事务可能会看到其他事务未提交的数据。所以在你的例子中线程一第二次读取到的数据将是线程二修改后的数据。Read Committed提交读在这个级别一个事务只能看到其他事务已经提交的数据。在你的例子中如果线程二在线程一第二次读取之前已经提交了事务那么线程一会读取到线程二修改后的数据。如果线程二还没有提交那么线程一将读取到线程二修改前的数据。Repeatable Read可重复读在这个级别一个事务在整个过程中看到的数据是一致的。也就是说在事务开始后不会再看到其他事务对数据的修改。在你的例子中线程一第二次读取到的数据将是线程二修改前的数据不论线程二是否已经提交了事务。Serializable可串行化这是最严格的隔离级别要求所有事务串行执行。这种级别可以防止所有的并发问题。
需要注意的是隔离级别越高数据的一致性越好但是并发性能可能会降低。所以在实际的系统中需要根据实际的需求和性能要求来选择合适的隔离级别。
6.3 mvcc的快照如何实现的
使用undo log日志最近一个日志也就是快照会被数据行的一个隐藏指针db_roll_ptr指向
6.4 写sql
有一个teacher表字段是id和name还有一个t_s表表示teacher-student有字段tid,sid。现在让你查询学生数大于10个的老师。
select t.name from teacher t left join t_s ts on t.idts.id group by t.id having count(ts.sid)10
6.5 数据库的隔离级别都是针对读操作的吗
数据库的隔离级别针对的不仅仅是读操作也包括写操作。但往往我们更关注读操作的一致性因为在并发环境下不同的隔离级别会对读操作产生不同的影响比如脏读、不可重复读和幻读等问题。而写操作通常是由数据库的并发控制机制如锁来保证一致性的。
6.6 事务本身不能保证对写的保护需要配合锁一起完成
你是对的。事务只是提供了一种机制确保由一组数据库操作构成的逻辑工作单元要么完全完成要么完全不完成这就是事务的原子性。但事务本身并不能防止多个事务并发地修改同一份数据这可能会导致数据的不一致。
为了解决这个问题数据库系统通常会使用锁等并发控制机制来防止并发事务之间的冲突。当一个事务试图修改一份数据时数据库系统会给这份数据加锁防止其他事务同时修改这份数据。直到这个事务完成提交或者回滚并释放锁其他的事务才能修改这份数据。
这就是为什么我们说数据库的隔离级别提供了对写操作的保护。实际上这种保护是由数据库的并发控制机制如锁来实现的不同的隔离级别使用了不同的并发控制策略因此提供了不同程度的写操作保护。
7 串行化相关问题
7.1 串行化一定能保证读取的数据是最新的对吧
是的串行化是数据库隔离级别中最高的级别它可以保证事务串行执行从而避免并发执行的事务产生的各种问题包括读取的数据不是最新的问题。在串行化级别下事务的执行结果和它们串行执行的结果一致。
7.2 串行化的事务是数据库中的所有事物吗还是某一张表的关联事务串行化的粒度有多大
串行化的粒度取决于具体的数据库管理系统和它的并发控制机制。在一些数据库系统中串行化可能会锁定整个数据库使得所有的事务都必须串行执行。在其他一些数据库系统中串行化可能只会锁定被事务访问的数据使得访问不同数据的事务可以并行执行。
mysql中串行化的粒度有多大
MySQL中的串行化SERIALIZABLE隔离级别会对所有的读操作都加锁以防止其他事务并发修改数据从而实现事务的串行执行。这意味着在同一时间只有一个事务能够对同一份数据进行操作。所以可以说MySQL的串行化隔离级别在数据行级别上进行的具体的粒度取决于事务操作的数据范围。
7.3 串行化机制是不是也可以在客户端实现比如消息队列单线程消费的场景
是的串行化机制并不局限于数据库它可以应用在任何需要并发控制的场景。比如在消息队列中你可以让每个消费者线程处理一部分消息使得不同的消费者线程处理的消息不会有交集这样就可以达到类似于串行化的效果。但需要注意的是这种方法依赖于消息的分配策略如果消息不能均匀地分配给每个消费者线程那么消费者线程可能会出现空闲导致系统的吞吐量下降。