自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(113)
  • 收藏
  • 关注

原创 【字少图多剖析微服务】深入理解Eureka核心原理

增量拉取返回的服务实例列表会合并到Eureka客户端的本地缓存中,然后根据本地缓存的服务实例列表计算一个hashCode,与Eureka服务端返回的hashCode进行比较,如果不一致,还要再进行一次全量拉取。当ApplicationResource接收到服务注册请求时,会把服务实例信息写入内存注册表,并失效掉读写缓存,然后把新注册上来的实例信息异步同步到集群中的其他Eureka节点。以上就是Eureka全部的核心原理,下面放一张源码图,对源码有兴趣的可以跟一跟,没有兴趣的可以直接忽略。

2024-07-20 11:25:05 515

原创 【深入理解SpringCloud微服务】浅析微服务注册中心Eureka与nacos,手写实现一个微服务注册中心

最后,我们接入SpringBoot提供的自动装配机制,完成我们注册中心的自动配置,spring.factories文件配置指定我的配置类RegistryCenterServerConfig,然后我们的配置类RegistryCenterServerConfig通过@ComponentScan注解扫描RegistryCenterController、RegistryCenterService、定时任务类等一些核心类,定时任务使用Spring的@EnableScheduling和@Scheduled注解。

2024-07-20 11:22:58 327

原创 【图解大数据技术】流式计算:Spark Streaming、Flink

Flink 和 Spark Streaming 不一样,Flink 一开始设计就是为了做实时流式计算的。它可以监听消息队列获取数据流,也可以用于计算存储在 HDFS 等存储系统上的数据(Flink 把 这些静态数据当做数据流来进行处理)。然后 Flink 计算后生成的结果流,也可以发送到其他存储系统。

2024-07-13 10:06:08 1095

原创 【图解大数据技术】Spark

Spark与MapReduce一样,也是大数据计算框架。Spark相比MapReduce拥有更快的执行速度和更低的编程复杂度。Spark Core:封装了Spark的基本功能,比如RDD、任务调度等。Spark SQL:Spark SQL可以处理结构化数据,当我们遇到结构化数据的计算时,可以使用Spark SQL,它允许我们把数据集映射为表结构,然后像操作关系型数据库的库表一样操作Spark SQL的表。

2024-07-13 10:04:03 975

原创 手写实现一个ORM框架

首先介绍一下ORM框架的相关知识。数据库表是行列格式的,而Java是面向对象的,我们需要通过操作JDBC的结果集ResultSet,一行行遍历,再一列一列的处理结果,在new一个对象去set对应的值,这就显得非常繁琐,也与Java的面向对象编程格格不入。ORM框架就可以解决这个问题,通过对象与关系型数据库建立一个映射关系,就可以省去操作JDBC的结果集ResultSet这一步繁琐的操作,直接把对库表的查询结果映射成对应的对象。

2024-07-06 18:18:10 841

原创 【图解大数据技术】Flume、Kafka、Sqoop

Flume是一个数据采集工具,多用于大数据技术架构下的日志采集。Flume的特点是高可靠,高可用,分布式,海里数据采集传输。Agent:一个Agent就是一个JVM进行,Agent中主要由Source、Channel、Sink三部分组成。Source:Source主要负责收集外部的数据到Agent中,以Event的形式存入Channel。Sink:Sink负责从Channel中批量删除Event并把它们写入指定的外部存储。

2024-07-06 18:15:16 915

原创 【图解大数据技术】Hive、HBase

HBase是一个用于存储海量非结构化或半结构化数据的列示存储数据库,支持高性能写入,准实时查询。HBase底层基于HDFS实现了PB级别的海量数据存储。通过缓存和预写日志技术实现了高性能写入和低延迟查询。通过Zookeeper的监控通知HMaster故障转移实现了高可靠性。通HMaster接收RegionServer注册以及HMaster的RegionServer集群负载均衡能力实现高扩展性。

2024-06-29 21:41:43 1101

原创 【图解大数据技术】Hadoop、HDFS、MapReduce、Yarn

MapReduce是一个分布式离线计算框架,专门用于处理大数据场景中与实时性无关的一些离线计算任务。MapReduce的数据输入一般是HDFS,然后经过InputFormat进行输入格式化,变成格式;然后执行用户实现的Mapper类型的map方法,进行数据映射,映射处理的结果也是格式;然后执行一个shuffle过程,对映射结果进行按key进行分组分区,把同一区域的所有KV发送到同一个Reducer,由一个节点进行;Reducer对同一个key分组下的所有value进行聚合操作;

2024-06-29 21:38:35 1469

原创 【图解IO与Netty系列】Netty源码解析——ChannelPipeline中的责任链模式

AbstractChannelHandlerContext的invokeChannelRead方法里面,一般会进入if条件分支,拿到ChannelHandlerContext的ChannelHandler,因为是处理read事件,read事件是入站事件,所以是ChannelInboundHandler类型,然后调用ChannelInboundHandler的channelRead方法进行事件处理,ChannelInboundHandler的channelRead方法就是我们实现的处理逻辑。

2024-06-22 11:49:43 751

原创 【图解IO与Netty系列】Netty源码解析——事件循环

就是通过allocator分配一个ByteBuf,然后把Channel中的数据读取到ByteBuf中,然后调用pipeline.fireChannelRead(byteBuf)触发ChannelPipeline的处理,然后ChannelPipeline中的ChannelHandler就会处理byteBuf中的数据,这里的ChannelPipeline中的ChannelHandler就是我们定义的ChannelInitializer组装到ChannelPipeline中的ChannelHandler了。

2024-06-22 11:48:33 1194

原创 【图解IO与Netty系列】Netty源码解析——服务端启动

今天我们一起来学习Netty源码,对Netty有一个深入的认知,既能掌握其使用和原理,又能对它底层的设计有一个大概的认知。

2024-06-16 16:22:41 775

原创 【图解IO与Netty系列】Netty编解码器、TCP粘包拆包问题处理、Netty心跳检测机制

网络传输是以字节流的形式传输的,而我们的应用程序一般不会直接对字节流进行处理,而是把字节流解析成有一定结构的数据格式再去处理。因此我们在发送数据时,要对我们的数据进行编码,把它转换成二进制字节流的形式,然后在网络中进行传输,当我们接收到对方传输过来的二进制字节流时,又需要对其进行解码,解析成应用程序能够处理的数据格式。根据不同的协议或不同的功能,Netty提供了对应的编码器或解码器,有处理SSL或TLS协议的、有处理HTTP协议的、有做HTTP压缩的、有处理WebSocket协议的等等。

2024-06-16 16:20:31 882 2

原创 【图解IO与Netty系列】Netty核心组件解析

Selector就是NIO中的Selector,Selector是一个多路复用器,我们可以往Selector注册多个Channel,Selector可以帮我们监听注册在其上的Channel,当我们调用Selector的select()方法时,当前线程就阻塞,通过Selector监听注册在其上的Channel,等待关注的事件就绪。除了持有NIO的Channel以外,还保存了各自关注的事件类型,等真正把NIO的Channel注册到Selector上的时候,就可以直接设置对应的事件类型。

2024-06-10 16:09:02 782

原创 【图解IO与Netty系列】Netty快速入门

Netty是高性能的网络通信框架,底层对Java的NIO进行了封装,特点是简单易用易上手,又能为应用提供高性能的网络通信能力。在网络通信场景中,我们一般使用Netty进行开发而不是NIO,因为Java的NIO使用非常的复杂,代码不易于维护。并且在网络通信中,我们需要对协议编解码、断线重连、心跳检测等问题进行处理,这些在NIO中都是不具备的,需要我们手动编码实现。而Netty则对NIO进行了封装,使得我们无需编写复杂的NIO代码,又能实现高性能的网络通信。

2024-06-10 16:04:50 966 1

原创 【图解IO与Netty系列】Reactor模型

Reactor模型是服务器端用于处理高并发网络IO请求的编程模型,与传统的一请求一线程的同步式编程模型不同的是,Reactor模型是基于事件驱动的响应式编程模型,可以一个线程处理多个请求,并且是异步处理,在高并发场景下,性能大大的提升。传统的同步式编程模型如下:服务端接收到请求后,从线程池中拿出一个线程(比如Tomcat里的线程池),经过Controller、Service、Dao的一顿处理,最后返回响应结果给客户端。这种同步处理请求的方式效率并不高,可以应对一些并发量不高的场景。

2024-06-01 20:23:27 958

原创 【图解IO与Netty系列】Java世界里的NIO

由于Socket编程有以上种种缺点,从JDK1.4开始就推出了NIO的编程模型。NIO是非阻塞式IO操作,性能比起过去的原生Socket编程在性能上有很大提升。但是要注意的是,Java的NIO与Linux的NIO不是一个东西,Java的NIO底层使用的其实是IO多路复用。

2024-06-01 20:20:05 806

原创 【图解IO与Netty系列】IO多路复用

于是就有了NIO,NIO是同步非阻塞式IO,在客户端未发送数据前,服务端用户线程线程调用read()函数不会阻塞,而是马上返回一个error,用户线程可以先干点别的事情,然后再次尝试read(),如果此时数据就绪,那么read()函数会阻塞,用户线程把内核空间的数据拷贝到用户空间。于是就是有了IO多路复用。epoll_create创建一个epoll实例,epoll实例使用一个红黑树结构保存注册进来的socket文件描述符,然后使用一个链表保存就绪的socket文件描述符,此时epoll实例还是空的。

2024-05-26 14:45:17 1174

原创 【图解IO与Netty系列】IO的同步与异步、阻塞与非阻塞,Linux五种IO模型

如果数据已经在内核空间了,那么当前线程调用read函数就会拷贝内核空间的数据到用户空间,这个拷贝的过程是同步读取,是当前线程主动拷贝的,因此在线程拷贝数据到用户空间的这段时间,程序是不会往下执行的。如果客户端发送的数据已被拷贝到内核空间,操作系统会发送一个SIGIO信号给当前线程,当前线程转而执行之前注册的SIGIO信号处理函数,里面会调用redvfrom读取内核空间的数据到用户空间,此时是由当前线程主动拷贝数据,因此从内核空间拷贝数据到用户空间期间当前线程阻塞,因此还是同步IO。BIO是同步阻塞式IO。

2024-05-26 14:42:18 745

原创 【图解计算机网络】TCP 重传、滑动窗口、流量控制、拥塞控制

比如按照上图的这个例子,如果ssthresh=8,那么当cwnd上涨到8时,就进入拥塞避免算法,此时每收到一个ack,cwnd就增加1/8,当收到8个ack时,cwnd才变成9,然后后面收到9个ack,cwnd才变成10。此时,由于有TCP的累计确认机制,如果中间有某个ack丢失,也不必重发,只要更大的ack被发送方接收到,就能确认前面的数据包都被接收到,发送方无需重发数据包,接收方的ack也不需要重发。有了滑动窗口,接收方就可以通过窗口控制发送方的发送速度,使得发送方不会无脑的发送。

2024-05-12 11:33:06 978 3

原创 【图解计算机网络】http1.1,http2.0,http3.0

当一个设备从一个网络迁移到另一个网络(比如手机从4G网络切换到WIFI),那么IP地址就会改变,而由于IP地址是组成TCP连接的四元组中的元素,IP地址改变意味着TCP四元组改变,这样就不是同一条TCP连接了,因此要重新经过TCP三次握手的流程建立新的TCP连接。这样显然效率是很低的,于是http1.1提供了长连接的优化。在http1.0的时候,一次http请求就要建立一次TCP连接,这一次的http请求完成以后,TCP连接就会断开,如果还要发起第二次的http请求,就要再建立一次TCP连接。

2024-05-12 11:31:56 789

原创 【图解计算机网络】简单易懂的https原理解析

摘要算法可以让数据接收方校验接收到的数据是否与数据发送方发送的数据一致。数据发送方通过一个约定好的hash算法,待传输的数据作为参数,算出一个hash值,把这个hash值与数据一起传输。接收到数据的一方,根据约定好的hash算法,利用接收到的数据作为参数,算法出一个hash值,然后把这个算出来的hash值与接收到的hash值进行比较,如果两hash值相等,则校验通过,否则校验不通过。通过摘要算法,数据接收方就可以验证数据发送方发来的数据是否完整,是否与数据发送方发出的数据一致。

2024-04-27 14:52:50 984 1

原创 【图解计算机网络】TCP协议三次握手与四次挥手

1、三次握手可以防止历史连接建立请求导致的错误连接初始化。比如我们有一个客户端向服务器发起握手请求,握手请求报文的seq num是90但是此时网络阻塞,导致握手请求的报文迟迟没有到达服务器。然后我们重启了客户端,此时重新发送连接建立请求的报文,这次报文的seq num是100,此时网络通畅了,seq等于90的握手请求比seq等于100的握手请求先到达。此时服务器会先响应一个ack等于91的响应报文,然后客户端接收到之后,会返回一个RST标志位为1的报文。RST标志位为1,表示这个连接要终止。

2024-04-27 14:50:47 1092

原创 【图解计算机网络】从浏览器地址输入到网页显示的整个过程

这时候就需要用到IP地址,通过DHCP我们的计算机已经拥有了自己的IP地址,然后通过DNS域名解析协议也获取到了目标服务器的IP地址,这时候通过目标服务器的IP地址在本机的路由表中查询匹配,就可以把我们的数据包发送到路由器。数据包到达了目标服务器所在子网的路由器时,也是经过相同的规则,通过目标IP地址在路由表中进行匹配,然后经过交换机转发到目标服务器,目标服务器接收到数据包之后处理请求,返回响应数据包,也是经过相同的流程到达我们的计算机。经过交换机的转发,我们的数据包就到了我们局域网的路由器。

2024-04-20 09:57:43 1268 1

原创 【图解计算机网络】网络协议分层解析

MAC地址还被交换机用于子网内的通讯,我们的服务器通过ARP协议获得路由器的MAC地址,然后交换机就可以通过路由器的MAC地址帮我们把数据包转发到路由器,路由器帮我们把数据包发送出去。比如我们的浏览器与服务器之间通过http报文通信,浏览器通过http报文描述它需要请求的服务器上的接口或资源,以及请求携带的参数,服务器通过http报文给浏览器返回指定的资源或接口响应的数据。应用层定义的是应用程序之间用于通信的报文格式,通过定义好格式的报文,按照一定的规则,应用程序就能互相通信,互相交换数据。

2024-04-20 09:53:43 750

原创 【Java虚拟机】三色标记、增量更新、原始快照、记忆集与卡表

然后用户线程才把到该对象的引用链断开,此时GC垃圾收集线程是不知道的,GC垃圾收集线程对于已经遍历过的对象,是不会再遍历的,因此该对象就会被当成存活对象被保留下来。但是在JVM中存在跨代引用的现象,也就是老年代的对象引用了年轻代的对象,或者是年轻代的对象引用了老年代的对象。但是JVM在进行年轻代的垃圾收集时,只会对年轻代进行扫描,不会扫描老年代,那么如果一个年轻代对象仅存在老年代对象对它的引用时,GC是扫描不到它的,自然就不会被标记为存活对象。如果是白色的对象,表示无法通过GC Roots的引用链访问到。

2024-04-14 10:41:35 971

原创 【Java虚拟机】简单易懂的ZGC原理分析

然后进入到下一轮垃圾收集时,就会使用M1标志位去标记存活的对象,那么在本轮垃圾收集中存活的对象的M1标志位就会被置为1,那么M1标志位没有被置为1的,就可以认为是垃圾对象,可以被清理,这里就包括了上一轮中存活的M0标志位被置为1的对象。有好处,自然也是有代价的。可以看到,有了染色指针和转发表,ZGC就可以在标记结束之后,就马上进行存活对象的转移了,并且用户线程是不需要停顿的,不需要停止用户线程等待存活对象转移完毕并且修正指针指向的值,也就没有了这部分STW的时间消耗,性能就大大提升了。

2024-04-14 10:32:54 946

原创 【Redis知识点总结】(七)——缓存雪崩、缓存穿透、缓存击穿、Redis高级用法

假设我们系统有1亿个用户,我们要统计在2024年1月28日当天这1亿个用户中有多少用户登录,我们可以用一个长度为1亿的bitmap,然后bitmap中每个bit对应一个用户当天的登录情况,登录了则置为1,否则该bit就是0,那么我们只要用一个bitcount命令就可以得到当天这1亿个用户的登录情况了。上面说到布隆过滤器是基于bitmap实现的,这个bitmap其实就是基于redis的string类型的,因为string会保存二进制字节数组,所以自然可以用它来实现bitmap的功能。

2024-03-24 11:32:04 717

原创 【Redis知识点总结】(六)——主从同步、哨兵模式、集群

哨兵节点自动组成集群,是通过主节点完成的,它们在主节点的“__sentinel__:hello”频道执行pub和sub命令,也就是进行发布订阅,pub命令把自己的ip地址和端口号发布到主节点的“__sentinel__:hello”频道上,sub命令订阅主节点的“__sentinel__:hello”频道,当其他哨兵节点把自己的ip地址和端口号发布到主节点的该频道,当前哨兵节点就可以订阅到其他节点的ip地址和端口号。主节点和从节点都可以接收读命令,从节点可以分担主节点的读请求压力,这样就实现了读写分离。

2024-03-24 11:30:20 959

原创 【Redis知识点总结】(五)——Redis实现分布式锁

在Redis的众多应用场景中,分布式锁是Redis比较重要的一个应用场景,今天我们就来了解一下如何用Redis实现一个分布式锁。

2024-03-17 21:43:41 1300

原创 【Redis知识点总结】(四)——如何保证缓存与数据库中的数据一致性

最后总结一下比较靠谱的几种做法。如果是强一致性的场景,是不适合使用缓存的,那么最好就不要使用缓存了。如果遇到了即要求强一致性,又追求高性能的场景,那就太变态了。如果是对一致性要求较高,但又不是强一致性,那可以使用canal同步的方案,正常情况下canal读取binlog同步数据到redis这个过程,处理是非常快的。如果对一致性要求不高,可以采用先更新数据库,后删除缓存的机制,并且在查询数据库加载数据到缓存时,给缓存设置一个过期时间。

2024-03-17 21:41:53 1249

原创 【Redis知识点总结】(三)——Redis持久化机制、内存淘汰策略、惰性删除机制

bgsave则会fork一个子进程进行RDB持久化,在进行持久化的时候,如果主线程发生读写操作修改内存中的数据,会使用COW(copy-on-write)技术,在内存中的数据块被修改前,把将被修改的数据块copy一份副本,让子进程读取副本进行持久化,保证子进程写到RDB文件中的快照数据的一致性。然后子线程会读取内存中的副本数据,生成新的AOF文件。在启用混合持久化时,Redis重启首先会读取AOF文件中的RDB内存快照,恢复到内存中,然后在读取后面的AOF日志,执行AOF日志记录的命令,应用到内存中。

2024-03-09 13:49:31 509

原创 【Redis知识点总结】(二)——Redis高性能IO模型剖析

整个Redis事件驱动框架的主体逻辑就是一个主线程的死循环,在循环中,当前线程调用epoll_wait进行监听,获取有事件就绪的socket,然后放入一个队列,所有socket都放入队列后,会遍历队列中的socket进行事件分派。如果是建立连接事件,则调用socket的accept()函数建立连接获取另一个socket,把该socket注册到epoll实例中,如果是有数据达到,则调用socket的read()函数读取数据,如果是有数据需要写出,则调用socket的write()函数。

2024-03-09 13:48:27 1257

原创 【Redis知识点总结】(一)——各种数据结构及其应用场景

Redis的基础数据类型包括String(字符串)、List(链表)、Hash(哈希)、Set(集合)、Sorted Set(有序集合)五种。

2024-03-02 13:33:09 954

原创 MySQL知识点总结(七)——主从复制、读写分离、高可用

当dump线程被用户线程唤醒后,就会进行binlog同步,把binlog日志中最新写入的内容同步到从节点,从节点的IO线程写入relay log成功后,响应主节点的dump线程,主节点的dump线程再去通知用户线程。不同的MySQL版本,提供的分发方式不一样,比如老版本的MySQL只支持按库分发,而新版本的MySQL则支持按行分发,使用的是哪种分发方式,这取决于MySQL的版本以及相应的配置,这里就不深入细说了。因此,主节点的写并发量过大时,从节点就会跟不上主节点的写入速度,造成主从延迟。

2024-03-02 13:30:30 1155

原创 MySQL知识点总结(六)——InnoDB底层架构

比如我们要查询id为1的一条记录,InnoDB就会查找到id为1的记录所在的数据页,把它加载到内存中,Buffer Pool就会把该数据页缓存起来,当我们下次再读取id为1的记录,或者与之相邻的同在一个数据页中的其他记录,就无需再从磁盘中把该数据页读到内存,而是直接在该页中查找并返回,这样就提升了查询性能。首先我们要明白一点,MySQL是以页(16KB)为单位进行读取,也就是即使我们查询的是一行数据,MySQL也会读取一个页到内存中,也就是磁盘中该行记录所在的数据页,这是基于局部性原理的一个设计。

2024-02-24 19:38:21 1294

原创 MySQL知识点总结(五)——锁

接下来分析一下,各种不同情况下InnoDB都是如何加锁的,加的是行锁?间隙锁?还是next-key lock?然后分别对哪些行记录加锁。在分析之前,我们首先要明白一点,InnoDB的行锁都是加在索引上的,也就是对索引上锁,InnoDB只会对扫描到的索引加锁,没有扫描到的索引是不会加锁的,并且只会对索引中被扫描到的行记录和间隙上锁。可重复读隔离级别下的加锁机制可重复读隔离级别下,加锁的原则是对被扫描到的索引行记录以及它前面的区间加临键锁next-key lock,但是等值查询时扫描到最后的一条不满足

2024-02-24 19:36:35 2562

原创 MySQL知识点总结(四)——MVCC

MVCC全称是Multi Version Concurrency Control,也就是多版本并发控制。它的作用是提高事务的并发度,通过MVCC机制,数据库可以不通过加锁,也能保证事务的隔离性。MySQL的InnoDB存储引擎也有自己的MVCC机制的实现,通过MVCC机制保证了“读已提交”和“可重复读”两个隔离级别下的隔离性。要理解MVCC,就要理解InnoDB里面的三样东西:“数据行记录中的三个隐式字段”、“undo log”、“read view”。理解了这三个东西,也就是理解了MVCC。

2024-02-03 11:08:24 1299

原创 MySQL知识点总结(三)——事务

当MySQL重启时,发现没有redo log,那么当前数据库的库表是不存在此次事务的修改的,但是binlog却记录事务的修改,同步到从库时,从库就比主库多了一次更新,于是又出现了主从不一致。比如先提交redo log,再记录binlog,此时就有可能出现这种情况:提交完redo log后MySQL宕机了,没来得及记录binlog,此时MySQL重启后,发现redo log是有的,于是当前库表的修改是生效的,但是如果我们配了主从同步,由于binlog上是没有修改记录的,因此同步到从库时,从库就少了一次修改。

2024-02-03 11:03:57 1033

原创 MySQL知识点总结(二)——explain执行计划、SQL优化

但是要注意的时,这里之所以扫描result表时MySQL走了索引,是因为不需要回表查询result表中需要返回的字段,如果返回结果中包含了result表中的某个字段,并且这个字段是“idx_score_studentno”中没有的,那么由于有回表查询的成本,MySQL就不会走这个索引。这样,因为索引中的score排列是有序的,MySQL就不需要进行文件排序,并且MySQL可以从联合索引中取到关联查询需要的studentno字段,因此,也不需要回表。in查询是拿in子查询的结果,到外层查询的表中进行匹配;

2024-01-28 20:15:21 1020

原创 MySQL知识点总结(一)——一条SQL的执行过程、索引底层数据结构、一级索引和二级索引、索引失效、索引覆盖、索引下推

回表一般是因为我们建立二级索引时只包含一个索引键,没有包含要查询的其他字段,如果我们建立二级索引时,连同其他需要查询返回的字段一起建立一个二级联合索引,使得需要查询返回的字段在二级索引叶子节点中都有,MySQL就不会回表,这时候二级索引一般都会生效。这样,MySQL通过二级索引进行查询时,发现二级索引的叶子节点已经包含了所有需要查询返回的字段,就不会再回表查询,这样查询性能就会大大提高,原本由于大量回表而导致二级索引失效,通过这种优化手段,会使得MySQL会选择这个二级索引进行查询。

2024-01-28 20:11:10 1301

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除