Java现在发布的版本很快,每年两个,但是真正会被大规模使用的是3年一个的LTS版本。每3年发布一个LTS(Long-TermSupport),长期维护版本。意味着只有Java8,Java11,Java17,Java21才可能被大规模使用。每年发布两个正式版本,分别是3月份和9月份。在Java版本中,一个特性的发布都会经历孵化阶段、预览阶段和正式版本。其中孵化和预览可能会跨越多个Java版本。所以大明哥在介绍Java新特性时采用如下这种策略:每个版本的新特性,大明哥都会做一个简单的概述。单独出文介绍跟编码相关的新特性,一些如JVM、性能优化的新特性不单独出文介绍。孵化阶段的新特性不出文介绍。首
又到年底了,又是好多小伙伴主动或者被动找工作的时候了,最近好多小伙伴,都问我有没有最新面试题,有!!肯定有!!我就把我看过的和整理过的面试题,以答案都整理好,整理了目前最新版的《互联网大厂面试题》,涵盖了所有的Java面试题,并且为了各位小伙伴更好地有针对性地刷题,大明哥按照技术类别将面试题分了类,包括:Java基础、Java并发、Spring、SpringBoot、设计模式、Redis、Kafka等等共25个分类,99个PDF文件。面试题:25个文件夹99个PDF,包括Java集合、JVM、多线程、并发编程、设计模式、Java、MyBatis、ZooKeeper、Dubbo、Elastics
上一个死磕Java专栏【死磕NIO】(当然写的不是很好,争取今年将它重写一遍)是**【死磕Netty】**的铺垫,对于我们Java程序员而言,我们在实际开发过程一般都不会直接使用JavaNIO作为我们的网络编程框架,因为写出一套高质量的JavaNIO程序并不是一件容易的事,除了JavaNIO固有的复杂性和bug之外,作为NIO服务端,我们要处理的事情太多了,如网络闪断、客户端认证、消息编解码、半包读写,客户端一样也有很多复杂的事情要处理,所以如果我们对JavaNIO没有足够了解,没有足够的网络编程经验的话,利用JavaNIO来编写一个高性能的稳定网络编程框架并不是一件容易的事。所以我们一般都不
回答MySQL高可用架构(HA)是一个综合方案,是为了确保数据库系统在发生故障时仍能正常运行,尽量减少停机时间和数据丢失。常用的高可用有主从复制、MySQLCluster、MGR等。一、高可用要求故障自动恢复当数据库发生宕机或其他故障时,能尽快自我恢复,尽可能减少停机时间。确保业务不会因为数据库故障而中断。数据一致性非主节点的数据应该和主节点数据保持实时或者最终一致性。当业务切换数据库时,切换前后数据库内容一致,不会出现数据丢失而影响业务二、高可用方案MySQL提供了多种技术方案来实现高可用性。如主从复制、MySQLCluster、MySQLGroupReplication等。主从复制主从复制
回答平滑扩容指数据库在扩容过程中继续对外提供服务,保障可用性。MySQL提供了多种方案如分区、水平拆分、主从复制、MGR等。一、分区扩容针对某个表数据量暴增,表分区是一个方案。分区(Partitioning)是将大型表拆分成更小的部分,每个部分称为分区。分区可以存储在不同的磁盘上,从而实现存储扩展。新建分区表,选择合适分区类型,如RANGE、LIST、HASH、KEY。CREATETABLEt_employee(idINT,nameVARCHAR(50)NOTNULLdefault'',departmentVARCHAR(50),hired_dateDATE,PRIMARYKEY(`id`))
回答组复制(GroupReplication)是MySQL5.7引入的一个服务器插件,它提供高可用、高扩展和高可靠的MySQL集群服务。它允许一组MySQL服务器之间通过消息传递相互交互,实现数据的一致性和服务的高可用。MGR实现原理1、主从复制传统的主从复制有一个主库,一个或多个从库。当主库执行并提交事务后,通过二进制日志(binlog)将事务相关的事件异步发送到从库以便重放。如此,所有服务器都拥有完整的数据副本。如图,半同步复制在异步复制的基础上增加了一个同步确认的步骤,确保主库提交事务时至少有一个从库已确认收到事务日志。MySQL的主从复制是一种提升系统并发和数据备份冗余的技术,但是其在
回答在数据库高可用架构中,主从不一致是常见的问题。对此,需先确认不一致的原因,再采取适当解决方案。通常,主从不一致的原因为延迟复制、网络问题和配置问题。后两者监控从库同步状态及时干预告警,而延迟复制可结合业务场景来解决。延迟复制1、数据库集群架构常见的数据库集群架构有一主多从、主从复制、读写分离。如上一个主库提供写服务,多个从库提供读服务。多个从库可以提升数据库整体读性能。2、主从库不一致主库和从库之间的数据同步具有一定时延,在此期间读从库,可能读到不一致的数据。3、优化方案针对数据库主从不一致问题,常见优化方案业务可以接受,系统不处理。大部分场景下,业务可以接受短时间数据不一致,如搜索、博客
回答GTID,全称为GlobalTransactionID(全局事务ID),是一个唯一标识已提交事务的编号,它是全局唯一的。GTID是在MySQL5.6版本引入的特性,主要用于简化主从复制的配置和管理,提高复制的可靠性。一、GTID构成GTID由server_uuid和transaction_id组成。其中server_uuid是数据库启动时自动生成,确保每台机器的server_uuid唯一。transaction_id是事务提交时由系统顺序分配的递增的序列号,用于标识在该服务器上提交的事务。二、GTID作用简化主从复制主从复制时,GTID方案使用master_auto_position=1代
回答MySQL通过server层的binlog实现数据复制,保障主备服务器的数据一致性。但主从复制会出现如下问题:异步复制延迟,MySQL的默认复制模式为异步复制,当网络延迟或数据库负载过高时,主库和备库会出现数据不一致现象。奔溃恢复不一致,也是因为异步复制,当主库提交事务后奔溃,变更数据尚未同步至从库,那么从库会丢失这些事务,从而导致数据不一致。GTID不一致,由于设置不当以及操作错误导致主从GTID不一致,从而出现主从库之间的数据偏差。确保主从复制数据一致性二进制日志(Binlog)MySQL主服务器将所有数据库变更记录在binlog中,然后从服务器同步这些日志文件并重放,恢复主库的数据变
回答MySQL主从复制的核心是主库Master写数据的同时记录binlog日志,而从库Slave同步Master记录的日志并执行重放,将变更同步至从库。主库Master在数据变更时(insert、update、delete等)记录binlog日志。从库Slave定时探测主库Master的binlog。主库Master为每个从库IOthread启动一个dumpthread,当主库发生变更时向从库发送binlog。从库Slave将收到binlog保存至本地的中继日志relaylog。再者,从库Slave启动SQLthread从中继日志relaylog读取变更数据并在本地重放中继日志主从复制结束后,
回答事务是指一组数据库操作作为一个逻辑上的整体,要么全部执行成功,要么全部不执行。ACID特性MySQL事务保证了数据库操作的可靠性和数据的一致性。MySQL的事务模型具有四个特性,即ACID:原子性(Atomicity),指事务是最小的执行单元,不允许分割。事务的原子性确保其要么全部完成,要么全部失败。一致性(Consistency),指执行事务前后,数据满足完整性约束,数据库保持一致性状态。隔离性(Isolation),指多个事务并发执行时,它们互相是隔离的。由于执行顺序的不同,可能出现“脏读”、“不可重复读”、“幻读”的问题,为了解决这些问题,引入了“隔离级别”的概念。持久性(Durab
回答MySQL中binlog又称为二进制日志。它记录所有变更数据库状态的语句,变更操作包括数据更新、表结构变更等。Binlog通常用于数据恢复、主从复制。再者,它是服务层的数据日志,所有MySQL存储引擎都支持。MySQL的binlog有三种格式:STATEMENT、ROW和MIXED。STATEMENTSTATEMENT格式记录原始的SQL语句。通常其产生较小的日志文件,并且因为是按照语句来记录,所以恢复也相对较快。但是,如果存在SQL依赖数据库服务器的环境变量或者涉及到随机数生成等,那么在主从复制时会出现数据不一致的问题。ROWROW格式记录对每一行数据所做的更改。这种格式的日志文件通常较
回答Binlog、Redolog和Undolog是MySQL设计的三种不同类型的日志。binlog是二进制日志,记录数据库所有更改状态的语句,如DDL和DML语句。redolog是重做日志,保证InnoDB存储引擎的事务持久性。当发生MySQL服务端故障,InnoDB在数据库启动时重放redolog来确保所有事务都正常提交,恢复至崩溃前状态。undolog是回滚日志,记录数据修改前的原始信息,用于事务的回滚和多版本并发控制(MVCC)。其中binlog是服务层的日志,数据存储在文件系统;而redolog和undolog是存储引擎层日志,存储在共享表空间或文件中。像MyISAM引擎不支持事务就没
回答不会重复。MySQL的自增主键机制(AUTO_INCREMENT)能够确保主键值的唯一性和递增性,不会出现重复问题。详解一、自增主键工作原理InnoDB存储引擎使用自增计数器(auto-incrementcounter)生成自增主键值。插入新纪录时,InnoDB根据当前计数器值生成新的主键,并将计数器值自增。核心设计如下:自增锁插入新纪录时,InnoDB会在表级别加自增锁(AUTO-INC锁),确保同一时间只有一个事务能获得新的自增主键值。自增锁是轻量级的,仅在生成新主键值时加锁,插入完成后立即释放。主键值持久化当事务提交时,保证新的自增主键值持久化。如此即使事务回滚,自增主键值也不会重复
回答自增ID指定义一个初始值,然后不停地往上加步长的数值字段。虽然自然数是没有上限的,但在计算机中会为字段定义类型,如idintunsigned,int占四个字节,那么它就有上限了。对于自增ID用完了的场景需要根据实际情况来分析:有主键和无主键。一、表定义的自增id当表定义的自增值达到上限后,再申请下一个id时,得到的值保持不变。故插入时会提升主键冲突错误。createtablet_test(`id`intunsignedauto_increment,`name`varchar(255)NOTNULLdefault'',PRIMARYKEY(`id`))ENGINE=InnoDB,auto_i
回答是的,Update语句where条件字段没加索引会锁全表。详细过程如下:1、InnoDB引擎支持行锁,当隔离级别为可重复读时,即InnoDB默认的事务隔离级别,**其加锁的基本单位是next-key锁(记录锁+间隙锁)。**next-keylock会锁住记录本身和记录之间的“间隙”,防止其他事务在这个记录区间插入新的记录,从而避免幻读现象。2、InnoDB间隙锁是在索引上而非行上。3、where条件字段没有使用索引,那么会全表扫描。相应的会对所有的记录加上next-key锁(gaplock+recordlock),相当于把整个表锁住。InnoDB引擎如何实现行锁?扩展一、数据准备CREAT
回答InnoDB是支持行级锁的存储引擎。大多数情况下,InnoDB加索引可以避免锁表。然而,具体情况取决于索引类型以及MySQL版本。如MySQL5.6之后,由于推出OnlineDDL功能不会锁表;加主键索引和唯一索引会锁表,而加普通索引不会锁表。扩展一、OnlineDDL从MySQL5.6开始,InnoDB引入了onlineddl功能,支持添加索引时减少对表的锁定,甚至避免锁表。在线DDL允许表在进行DDL操作(添加索引、删除索引、添加列等)时仍然支持读写操作。//常规加索引语句ALTERTABLEt_employeeADDINDEXidx_age(age);//显示指定算法和加锁模式,与上
回答在MySQL中,由于锁等待超时和死锁检测技术,出现死锁的频率不高。但一旦发生死锁会导致事务延迟或失败、系统吞吐量下降,最终影响用户体验性。线上环境应该尽量避免死锁,具体如下:1、避免大事务。大事务占用资源时间长,会增加与其他事务发生冲突的可能,确保事务规模小且持续时间短。事务大小由insert、update、delete的行数决定。2、保持一致性的锁定顺序。事务间的锁定顺序不一致,很容易出现资源互相依赖从而发生死锁。3、及时提交事务。变更操作完成后立即提交事务,避免长时间打开交互式会话,InnoDB事务自动提交(autocommit=1)默认开启。4、更改事务隔离级别。在读多写少的场景,可
回答死锁指并发系统中不同线程间出现循环资源依赖,涉及的线程都在等待别的线程释放资源时,导致这几个线程都进入无限等待的状态。在MySQL中,发生死锁,有两种解决策略:锁等待超时。指线程直接进入等待,直到超时。可通过innodb_lock_wait_timeout参数设置超时时间,在InnoDB中,默认超时时间为50S。死锁检测。指InnoDB发起死锁检测,发现死锁后,主动回滚死锁链条中的某一个事务,让其他事务能继续执行。可通过innodb_deadlock_detect=on/off开启关闭死锁检测,当然,对于高并发系统,开启死锁检测会降低整体性能。扩展死锁案例1、默认情况下,InnoDB只记录
回答MVCC(Multi-VersionConcurrencyControl)即多版本并发控制。它允许在不加锁的情况下进行读取从而减少读写操作间的冲突。MVCC是提高MySQL数据库并发性能的一个重要设计。通常,同一行数据在读写请求时,会通过加锁保证数据的一致性;而MVCC在遇到读写冲突时,让其读数据时通过快照读而不是当前读,快照读不需要加锁。MVCC实现机制在InnoDB的内部结构中,每行记录除了自定义的字段外,InnoDB还会隐式地为每一行添加三个字段:DB_TRX_ID,事务ID,长度为6个字节。记录最近修改该行的事务ID。DB_ROLL_PTR,回滚指针,长度为7个字节。回滚指针指向回
回答在MySQL中,主要通过**多版本并发控制(MVCC)和临键锁(next-keylock)**机制来解决幻读现象。一、幻读&不可重复读幻读指在一个事务中,同一条SELECT语句在不同时刻执行,得到不同的结果集的现象。比如由于其他事务的插入或删除操作,导致后面查询的结果集中出现了之前不存在的记录(幻影行)。数据库还有一个和幻读类似的概念不可重复读。两者的区别在于:幻读强调的是存不存在的问题,原来不存在的行记录,现在存在了,则是幻读。不可重复读强调的是变没变化的问题,行记录字段原来是A,现在却变为了B,则为不可重复读。二、MVCC机制MySQL默认的隔离级别是可重复读(RR),而MyS
回答在MySQL中,脏读、幻读以及不可重复读是指在并发事务环境中发生的一些数据读取异常情况。这些情况与事务的隔离级别密切相关,不同的隔离级别提供了不同程度的保护,以防止这些问题的发生。脏读脏读指一个事务读取了另一个未提交事务修改的数据的情况。如果这个未提交的事务最终被回滚,那么第一个事务读取到的数据就是“脏”的,因为它读取到了一个从未真正存在于数据库中的数据状态。不可重复读不可重复读指一个事务多次读取同一数据集合时,由于其他事务的更新操作,导致后面读取的结果与之前的结果不一致的现象。也就是说一个事务在两次查询之间无法保持数据的一致性。幻读幻读类似于不可重复读,但它指一个事务多次执行相同的范围查
回答OnlineDDL(在线数据定义语言)是MySQL5.6引入的技术。它允许在执行DDL操作时,减少或避免对表的锁定,提高系统的并发性能和可用性。工作原理复制原始表结构OnlineDDL在后台创建一个与原始表结构相同的临时表。应用变更(索引或表结构)在临时表上应用索引变更或其他表结构修改。保持数据同步在索引变更过程中,InnoDB维护一个变更缓冲区(changebuffer)来记录对原始表的写操作(插入、更新和删除),从而确保数据同步。批量更新变更OnlineDDL完成后,将缓冲区的变更批量应用到新的结构中。替换原始表最后,InnoDB将原始表替换为新的表结构。OnlineDDL是一项写时复
回答在MySQL中,乐观锁和悲观锁是数据库的并发控制策略。不同于库锁、表锁、行锁等数据库具体的锁结构,它更多是一种设计思想。实际上,乐观锁和悲观锁的思想应用广泛,不局限于某种编程语言和数据库。乐观锁乐观锁(OptimisticLocking)的核心思想是假设数据在大多数时间内不会发生冲突,因此乐观锁不会上锁。只是在事务提交时才会检查是否有冲突:如果有人修改了数据则放弃操作,否则执行操作。通常,乐观锁通过数据版本(Version)或者时间戳(Timestamp)来实现。很明显,乐观锁是通过在表中冗余额外字段来避免加锁,提升数据库并发能力。悲观锁悲观锁(PessimisticLocking)的核心
回答插入意向锁是一种间隙锁。指一个事务执行时,被其他事务阻塞,在行插入之前由insert语句设置,提前锁定的某一行。插入意向锁是InnoDB引擎在提高并发,减少死锁的优化。具有如下特点:阻塞等待。在InnoDB中,一个事务插入一条记录时,需先判断插入位置处是否被其他事务加了临键锁(next-keylock)。如有,插入操作会被阻塞并会加一个插入意向锁,表明有事务想要在该区间插入新纪录,现在处于等待状态。行级锁。插入意向锁是行锁而非意向锁,意向锁是表级锁。提升并发性。同一间隙锁区间内,非同一插入位置的多个插入意向锁互不影响,不需要互相等待。也就是说插入意向锁是锁住某个点,有助于提高插入并发性。这
回答意向锁是InnoDB表级锁,它是InnoDB支持多粒度锁定,解决表锁和行锁共存问题的方案。特点如下:意向锁指事务稍后会对表中的行加X锁(排它锁)或S锁(共享锁),也就说意向锁分为IX(意向排它锁)和IS(意向共享锁)。InnoDB引擎对表里某些记录加S锁前,必需先获得表上的IS锁或更强的锁。InnoDB引擎对表里某些记录加X锁前,必需先获得表上的IX锁。意向锁由InnoDB自动管理,以确保数据库的一致性和减少锁冲突,提高并发性能。意向共享锁和意向排它锁是表级锁,不会和行级的共享锁和排它锁发生冲突。而且意向锁之间也不会发生冲突,只会和排它表锁(LOCKTABLES...WRITE)发生冲突。
回答间隙锁(GapLock)是InnoDB存储引擎中的一种锁机制,用以防止幻读(PhantomRead)发生,支持数据库事务的可重复读。间隙锁锁定的不是具体的行记录,而是索引记录之间的范围。间隙锁的目的是防止其他事务在锁定范围内插入新的数据。间隙锁应用场景建表及初始化语句CREATETABLE`t_user`(`id`intNOTNULL,`age`intNOTNULL,`name`varchar(255)NOTNULLdefault'',PRIMARYKEY(`id`),KEY`idx_age`(`age`))ENGINE=InnoDB;insertintot_user(id,age,nam
回答InnoDB默认的事务隔离级别是可重复读(RepeatableRead),InnoDB在该隔离级别下使用临键锁(Next-keyLock)。临键锁能解决幻读问题(PhantomReads),即保证事务在执行期间不会看到其他事务插入的行。临键锁的加锁规则如下:加锁的基本单位是next-keylock。而next-keylock=gaplock+recordlock,加锁区间为前开后闭。查找过程中访问到的对象才会加锁。即回表时会对主键索引和二级索引都加锁,而覆盖索引查询则仅在覆盖索引上加锁。索引上的等值查询,给唯一索引加锁的时候,next-keylock退化为行锁。索引上的等值查询,向右遍历时
回答InnoDB行级锁作用于数据库表的单行,粒度更小,有助于降低锁竞争,提高并发性。实现机制如下:**1、存储引擎。**MySQL行级锁在存储引擎层实现,InnoDB支持行锁,而MyISAM不支持行锁。2、加锁机制。InnoDB行锁是对索引上的索引项进行加锁,而非针对记录加锁。也就是说只有通过索引条件检索数据,InnoDB才会使用行级锁;否则,InnoDB将使用表锁。3、基本单位。InnoDB行级锁加锁的基本单位是临键锁(Next-keyLock,临键锁=记录锁+间隙锁)。它是解决幻读,确保可重复读(RR,默认事务隔离级别)的关键。当使用记录锁(RecordLock)或间隙锁(GapLock)
回答MySQL的锁机制用于处理数据库并发控制,确保数据的一致性和完整性。它分为全局锁、表级锁和行级锁。一、全局锁(GlobalLock)全局锁指对整个数据库加锁,让整个数据库处于只读状态,所有更新操作停止。全局锁通常用于全库备份。FTWRL//全库只支持查询操作,DML、DDL以及事务类语句会被阻塞。//正在进行的写操作在执行完毕后被阻塞,不能再进行新的写操作。//锁定期间,所有对表的读操作仍然可以进行,但是写操作被阻塞。FLUSHTABLESWITHREADLOCK;//执行备份操作……//解锁,恢复正常UNLOCKTABLES;FTWRL可以确保全库备份的一致性视图,避免备份过程中数据不一
回答orderby子句对查询结果进行排序,确保返回结果集按照指定列或表达式的升序或降序排列。查询SQL中有orderby子句并不一定会执行排序。判断语句是否执行了排序可查看执行计划中的Extra字段。如果该字段存在Usingfilesort则说明执行了排序操作,反之则没有执行排序操作。如下:mysql>explainSELECT*fromt_userwhereage=10ORDERBYnamedesc;+----+-------------+--------+------------+------+---------------+---------+---------+-------+-
回答BufferPool是InnoDB内存的一块缓存区,用于缓存表和索引数据。BufferPool设计目标是提高磁盘IO效率,通过在内存中缓存数据页来减少磁盘读取和写入操作。它不仅加快了读取速度,还优化了写入性能。默认情况,BufferPool的数据页大小(page)和磁盘的页大小是一致的(16KB)。通过命令innodb_buffer_pool_size查看buffer_pool大小。mysql>showvariableslike'%innodb_buffer_pool_size%';+-------------------------+-----------+|Variable_na
回答在MySQL中,页分裂(PageSplit)指一个数据页已满且需要插入新的记录时,InnoDB将当前数据页的部分记录迁移到一个新的页中,以便新纪录的插入。通常发生在插入记录时。页合并(PageMerge)指一个数据页的使用率低于阈值时,InnoDB会将该页的记录合并到相邻的页中,并释放该数据页。通常发生在删除记录时。页分裂一、页分裂过程定位数据页,找到需要插入新纪录的数据页。页分裂,将该数据页一分为二,创建一个新的数据页。移动记录,将一半的记录从原页移动至新页。更新,更新B+树内部节点,以映射新的页结构。InnoDB的索引结构是B+Tree,它是一颗有序的平衡多叉树。插入数据时,根据主键定
回答理论上,MySQLInnoDB不限制单表的大小,其更多是受操作系统和硬件资源限制。在官方文档介绍中,InnoDB最小表空间略大于10MB,最大表空间取决于InnoDB页大小。若按默认值16KB计算,则最大表空间大小为64TB。在InnoDB中,一张表会生成两个文件:.frm文件(表结构文件)和.ibd文件(数据文件如聚簇索引和二级索引,也称为表空间)。扩展MySQL单表数量限制为2kw?单表2kw大小的限制,更多是从性能来考虑的,如SQL查询性能和索引维护成本。下面粗略分析下:1、数据页。InnoDB将数据划分为若干个页,以页作为磁盘和内存之间交互的基本单位,InnoDB中页的默认大小为1
回答Hashjoin是MySQL8提供的一种join算法,它比传统的NestedLoopJoin和SortMergeJoin更为高效。Hashjoin的基本思想是使用散列(哈希)技术来加速连接操作。扩展HashJoin工作原理HashJoin的执行分为两个阶段:构建阶段build探测阶段probe对于如下SQLSELECTt1.id,t1.NAME,t2.balanceFROMt_usert1JOINt_accountt2ONt1.id=t2.user_id1、构建阶段build从参与join的2个表中选择占空间小的那张表(不是行数少的),此处假设选择了t_user表。对t_user表中每行的
回答orderby子句对查询结果进行排序,确保返回结果集按照指定列或表达式的升序或降序排列。查询SQL中有orderby子句并不一定会执行排序。判断语句是否执行了排序可查看执行计划中的Extra字段。如果该字段存在Usingfilesort则说明执行了排序操作,反之则没有执行排序操作。如下:mysql>explainSELECT*fromt_userwhereage=10ORDERBYnamedesc;+----+-------------+--------+------------+------+---------------+---------+---------+-------+-
回答索引是一把双刃剑,一方面它可以提升查询效率;再者DML操作需维护索引,产生额外性能开销。故设计索引时需结合业务场景,从索引类型、字段区分度、覆盖索引、联合索引、前缀索引等方面综合考虑。一、基本原则选择合适的列进行索引频繁作为查询条件的列,索引应添加在where子句中频繁使用的列上。用于连接的列,对于多表连接查询,索引应添加在连接条件的列上。用于排序的列,为ORDERBY子句的列添加索引,保证查询结果集天然有序。用于分组的列,索引将数据按照某种顺序进行存储从而加快索引,为GROUPBY子句的列添加索引能加速分组查询。索引的区别度高选择性,选择性高的列(唯一值较多)适合作为索引,因为它们能有效
回答在数据库表加索引是为了快速定位到记录,提高查询效率。但在某些场景下,虽然加了索引,SQL执行中却没有走索引,而是全表扫描,这个过程称为索引失效。从前面的文章可知MySQLInnoDB引擎的索引结构是B+树。知道MySQL索引的结构吗?什么是聚簇索引和二级索引也正是因为InnoDB的B+树索引结构会出现如下索引失效场景。1非等值条件查询如likeselect*fromt_userwherenamelike'%a%';优化措施:对于like模糊匹配场景,通常结合实际业务改造为like'a%'2联合索引非最左前缀查询select*fromt_userwhereage=10andname='aa'
回答索引合并(IndexMerge)是MySQL5.1推出的优化技术,允许查询在没有复合索引的情况下,利用多个单列索引来提高查询性能。当一个查询的where子句包含多个条件,且这些条件分别适用于不同的索引,MySQL会将这些索引合并起来使用,减少回表次数,提升性能。索引合并支持合并单表索引,不能合并跨表的索引。扩展索引合并案例1、初始化数据CREATETABLEt_employee(idINTAUTO_INCREMENTPRIMARYKEY,nameVARCHAR(50),ageINTNOTNULL,contact_phoneVARCHAR(20),departmentVARCHAR(50))
回答索引下推(ICP)是MySQL5.6引入的优化,指在索引遍历过程中,对索引中包含的字段先做判断,直接过滤掉不满足条件的记录,减少回表次数,提升检索性能。索引下推中的下推是指在MySQL查询中,将部分Server负责的事情,下推交给了存储引擎Engine处理。无ICP之前。存储引擎先读取二级索引记录,根据索引中的主键值读取完整的行记录后(回表),再将行记录交给Server层检测该记录是否满足where条件。**引入ICP优化后。**存储引擎读取二级索引记录,先判断where条件能否用二级索引中的列过滤,条件不满足则处理下一行记录,条件满足则再使用索引中的主键去读取完整的行记录(回表)。最后,
回答不一定。这跟SQL查询的字段集是否全部命中索引有关。如果全部命中了索引,则不需要回表查询,否则就需要通过非聚簇索引上的主键值再去主键索引树查询一次行记录。在SQL查询中,一条能覆盖查询中所有字段的索引称为覆盖索引**。**覆盖索引能减少树的搜索次数,显著提升查询性能,是SQL性能优化的常用手段。扩展下面用一个例子演示下。一、初始化数据定义一张用户表(t_user)CREATETABLE`t_user`(`id`intNOTNULL,`age`intNOTNULL,`name`varchar(255)NOTNULLdefault'',PRIMARYKEY(`id`),KEY`idx_age`
回答聚簇索引的叶子节点数据行与键值存储在一起。在InnoDB中,聚簇索引通常就是主键索引,一张表只有一个聚簇索引。聚簇索引是一种数据存储方式,而不是新的索引类型。二级索引的叶子节点内容是主键的值。在InnoDB中,非主键索引称为二级索引,二级索引的键值和数据不在一棵树上。通常来说,基于MySQL二级索引的检索是先通过二级索引找到主键索引的键值,再通过主键值查询主键索引。扩展聚簇索引和二级索引检索过程通过聚簇索引来查询数据时,InnoDB可以利用索引树(B+树)来定位到具体的数据页。由于聚簇索引的数据行与索引是存储在一起的,所以一旦找到了索引项,那么对应的数据也就找到了。而二级索引的检索和数据不
回答正如图书的目录用于检索,数据库索引是为了提高数据查询效率。MySQL的默认存储引擎是InnoDB,它支持两种索引结构:B+树索引和HASH索引。在InnoDB中,B+树作为默认的索引结构。数据结构上,B+树是二叉树的升级版,它是一颗多路平衡查找树。数据存储上,B+树非叶子节点只存放键,不存放值;叶子节点同时存放键和值。B+树叶子节点间通过链表相连。相较于B树,B+树由于只有叶子节点存储数据,其他节点仅保存索引键和指针,那么相同磁盘块大小下,B+树可以存储更多的节点数据,树的高度也就降低了,对应查询效率就快。由于B+树所有数据都存放在叶子节点,且它是一颗自平衡树,故其数据的整体查询会更稳定,
回答更新SQL的执行过程与查询数据的流程类似。如updatet_usersetage=10whereid=12的执行过程如下(存储引擎默认为InnoDB):1、客户端:客户端基于网络连接到MySQL服务器,发送更新SQL语句到服务器。2、Server层:Server层接收到更新请求后,分析器通过词法分析和语法分析生成语法分析树知道这是条更新语句。优化器基于语法树(AST)选择合适的索引生成执行计划,如上述SQL会使用ID这个索引。执行器根据执行计划调用存储引擎API先找到这一行数据,再更新对应字段。执行器生成更新操作的BinLog,并把BinLog写入磁盘(备注:此处执行器记录BinLog操作
回答MySQL架构上分为Server层和存储引擎层。Server层主要负责连接处理、授权认证、SQL解析、分析优化、缓存等功能,而存储引擎层负责数据的存储和提取。对于一条查询SQL的执行过程如下:1、客户端连接:客户端基于网络连接到MySQL服务器,发送查询请求到服务器。客户端通常会维护一个数据库的连接池以减少连接创建和销毁的开销,这是提升性能的通用设计。2、查询缓存:当MySQL服务端开启了缓存,一条查询SQL语句会先判断缓存中是否包含当前SQL语句的键值对。如果有则直接将对于结果返回。如果表更改,则该表的所有查询缓存都会失效并从缓冲池中删除。3、SQL分析:MySQL会对SQL进行词法分析
回答MySQL的默认存储引擎从5.5版本开始被设置为InnoDB。主要原因是其具有高可靠和高性能特点,具体如下:事务支持:InnoDB支持事务处理,遵循ACID原则,这对于数据的准确性至关重要。行级锁定和MVCC:相比于MyISAM的表级锁,InnoDB提供了行级锁定。行级锁定减少数据库操作间的锁定竞争,提高了MySQL的并发。同时,通过多版本并发控制(MVCC)机制,InnoDB能有效降低锁的竞争,提升读取性能。**支持聚簇索引:**InnoDB使用聚簇索引作为其主要数据存储机制,它将数据行直接存储在主键索引的叶子节点,可减少数据访问IO次数,提升查询性能。外键约束:InnoDB支持外键约束
回答单纯的select语句是不会加锁的,但是使用select...forupdate查询时,MySQL会加排他锁,至于是行锁还是表锁,需要根据实际情况来确认:没用索引/主键的话就是表锁,否则就是是行锁。分析环境准备新建如下一张表结构CREATETABLEuser(idINT(5)NOTNULLAUTO_INCREMENT,nameVARCHAR(64)DEFAULTNULL,ageINT(3)DEFAULTNULL,codeVARCHAR(255)DEFAULTNULL,PRIMARYKEY(id),KEYidx_name(name)USINGBTREE)ENGINE=INNODBAUTO_I
建议MySQL数据库字段要设置NOTNULL。这句建议你可能听过很多人说过,也见过一些规范里面有写,但是你有没有仔细想过为什么呢?对于是说过NOTNULL还是NULL,其实都有一定的道理,没有强制要求,对错之分,都是规范而已。建议设置为NOTNULL一般是基于如下几个理由。为了下面案例的演示,我们需要使用如下表结构和数据:CREATETABLEuser(idbigint(20)PRIMARYKEYAUTO_INCREMENTcomment'id',namevarchar(20)comment'姓名',genderchar(1)comment'性别1男0女')ENGINE=InnoDBDEFAU