Mysql 查询优化之 Using filesort
Mysql 查询优化之 Using filesort最近在优化分页查询的时候,遇到了一个问题,如下(基于Mysql Innodb)
我们先建一个user表,其中有自增主键、user_id 也建立索引,create_date暂时不建索引,省略其他字段。
1234567CREATE TABLE `user_filesort_test` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键', `user_id` bigint(20) NOT NULL DEFAULT '0' COMMENT '员工id', `create_date` datetime NOT NULL DEFAULT '1970-01-01 00:00:00' COMMENT '创建日期', PRIMARY KEY (`id`), KEY `idx_user_id` (`user_id`) )
当分页查询的时候,打印执行计划,Extra 一栏出现了 Usin ...
MySQL深分页场景下的性能优化
1、什么是分页查询分页查询指的是将一个比较大的数据集分成多个小块(即“页”),并在用户请求时只返回用户需要的那一页的数据。既方便用户查看结果,也能以减少数据传输和处理的时间和资源消耗。
分页查询通常需要指定每页要显示的记录数量(Page Size)和要查询的目标页数(Page)。在进行分页查询时,通常会使用 LIMIT offset, pageSize 的方式来指定要查询的记录范围。
例如,如果要查询第 3 页(Page=3),每页显示 10 条记录(PageSize=10),那么可以使用以下 SQL 查询语句:
123SELECT * FROM table_name LIMIT 20, 10
20 就是 offset(偏移量),表示从第 21 条开始查。
Page 与 offset 的关系为:offset = (Page - 1) * PageSize
123SELECT * FROM table_nameLIMIT (Page - 1) * PageSize, PageSize
2、什么是深分页查询深分页查询指的就是在分页查询中,页码(Page)比 ...
Tcp协议
粘包与拆包TCP在接受数据的时候,有一个滑动窗口来控制接受数据的大小,这个滑动窗口你就可以理解为一个缓冲区的大小。缓冲区满了就会把数据发送。数据包的大小是不固定的,有时候比缓冲区大有时候小。如果一次请求发送的数据量比较小,没达到缓冲区大小,TCP则会将多个请求合并为同一个请求进行发送,这就形成了粘包问题;如果一次请求发送的数据量比较大,超过了缓冲区大小,TCP就会将其拆分为多次发送,这就是拆包,也就是将一个大的包拆分为多个小包进行发送。
TCP粘包/拆包解决策略TCP 是面向连接的传输协议,TCP 传输的数据是以流的形式,而流数据是没有明确的开始结尾边界,所以 TCP 也没办法判断哪一段流属于一个消息;TCP协议是流式协议;所谓流式协议,即协议的内容是像流水一样的字节流,内容与内容之间没有明确的分界标志,需要认为手动地去给这些协议划分边界。粘包时:发送方每次写入数据 < 接收方套接字(Socket)缓冲区大小。拆包时:发送方每次写入数据 > 接收方套接字(Socket)缓冲区大小。
UDP不会发生粘包问题:UDP具有保护消息边界,在每个UDP包中就有了消息头(U ...
http协议
GET 与 POSTget-和-post-有什么区别GET 和 POST 有什么区别?
根据 RFC 规范,GET 的语义是从服务器获取指定的资源,这个资源可以是静态的⽂本、⻚⾯、图⽚视频
等。GET 请求的参数位置⼀般是写在 URL 中,URL 规定只能⽀持 ASCII,所以 GET 请求的参数只允许
ASCII 字符 ,⽽且浏览器会对 URL 的⻓度有限制(HTTP协议本身对 URL⻓度并没有做任何规定)。
根据 RFC 规范,POST 的语义是发送数据并对指定的资源做出处理,具体的处理⽅式视资源类型⽽不同。
POST 请求携带数据的位置⼀般是写在报⽂ body 中,body 中的数据可以是任意格式的数据,
只要客户端与服务端协商好即可,⽽且浏览器不会对 body ⼤⼩做限制。
GET 和 POST ⽅法都是安全和幂等的吗?先说明下安全和幂等的概念:
在 HTTP 协议⾥,所谓的「安全」是指请求⽅法不会「破坏」服务器上的资源。
所谓的「幂等」,意思是多次执⾏相同的操作,结果都是「相同」的。
如果从 RFC 规范定义的语义来看:GET ⽅法就是安全且幂等的,因为它是「只读」操作, ...
一些容易搞混的知识点
进程状态
创建状态
进程由创建而产生,创建进程是一个非常复杂的过程,一般需要通过多个步骤才能完成:如首先由进程申请一个空白的进程控制块(PCB),并向PCB中填写用于控制和管理进程的信息;然后为该进程分配运行时所必须的资源;最后,把该进程转入就绪状态并插入到就绪队列中
就绪状态
这是指进程已经准备好运行的状态,即进程已分配到除CPU以外所有的必要资源后,只要再获得CPU,便可立即执行,如果系统中有许多处于就绪状态的进程,通常将它们按照一定的策略排成一个队列,该队列称为就绪队列,有执行资格,没有执行权的进程
运行状态
这里指进程已经获取CPU,其进程处于正在执行的状态。对任何一个时刻而言,在单处理机的系统中,只有一个进程处于执行状态而在多处理机系统中,有多个进程处于执行状态,既有执行资格,又有执行权的进程
阻塞状态
这里是指正在执行的进程由于发生某事件(如I/O请求、申请缓冲区失败等)暂时无法继续执行的状态,即进程执行受到阻塞,此时引起进程调度,操作系统把处理机分配给另外一个就绪的进程,而让受阻的进程处于暂停的状态,一般将这个暂停状态称为阻塞状态
终止状态
线程的状态
新建状态 ...
内存管理
内存管理逻辑地址和物理地址
我们编程一般只有可能和逻辑地址打交道,比如在 C 语言中,指针里面存储的数值就可以理解成为内存里的一个地址,这个地址也就是我们说的逻辑地址,逻辑地址由操作系统决定。
物理地址指的是真实物理内存中地址,更具体一点来说就是内存地址寄存器中的地址,物理地址是内存单元真正的地址。
编译时只需确定变量x存放的相对地址是100 ( 也就是说相对于进程在内存中的起始地址而言的地址)。
CPU想要找到x在内存中的实际存放位置,只需要用进程的起始地址+100即可。
相对地址又称逻辑地址,绝对地址又称物理地址。
内存管理有哪几种方式块式管理(连续)将内存分为几个固定大小的块,每个块中只包含一个进程,如果程序运行需要内存的话,操作系统就分配给它一块,如果程序运行只需要很小的空间的话,分配的这块内存很大一部分几乎被浪费了,这些在每个块中未被利用的空间,我们称之为碎片。
在 Linux 系统中,连续内存管理采用了 伙伴系统(Buddy System)算法 来实现,这是一种经典的连续内存分配算法,可以有效解决外部内存碎片的问题。伙伴系统的主要思想是将内存按 2 的幂次划分(每一块 ...
DCL问题的根源已经解决方案
DCL:Double Check Lock(双重检查锁)public static Singleton getInstance() {
// 一次检查(非同步)。
if (Objects.isNull(singleton)) {
synchronized (Singleton.class) {
// 二次检查(同步)。
if (Objects.isNull(singleton)) {
singleton = new Singleton();
}
}
}
return singleton;
}
双重检查锁(DCL)的失效原因在jvm底层new Singleton()时其实执行了三行代码:
1234//伪代码memory = allocategories();//分配空间ctorInstance(memory) //初始化对象singleton ...
如何防止重复提交
如何防止重复提交
前端拦截
后端拦截
前端拦截
前端拦截是指通过 HTML 页面来拦截重复请求,比如在用户点击完“提交”按钮后,我们可以把按钮设置为不可用或者隐藏状态。
代码:
1234567891011121314<html><script> function subCli(){ // 按钮设置为不可用 document.getElementById("btn_sub").disabled="disabled"; document.getElementById("dv1").innerText = "按钮被点击了~"; }</script><body style="margin-top: 100px;margin-left: 100px;"> <input id="btn_sub" type="button" ...
HashMap原理
HashMap
HashMap 与 HashSet 一样,不保证存储的顺序,因为底层是以 hash 表的方式存储的;
HashMap 底层存储结构为 数组 + 链表+红黑树 (Java 8);
HashMap 存储的 key-value 数据类型为 HashMap$Node 类型,该类型实现了 Map$Entry 接口;
HashMap 没有实现同步,因此是线程不安全的;
HashMap 中的几个常量/变量12345678910111213static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // 默认的 table 数组容量 aka 16static final float DEFAULT_LOAD_FACTOR = 0.75f; // 默认加载因子为 0.75static final int MAXIMUM_CAPACITY = 1 << 30; // 集合最大容量的上限是:2的30次幂(符号位为0)static final int TREEIFY_THRESHOLD = 8; // 链表树化临 ...
ArrayList 扩容机制分析
ArrayList 核心源码解读这里以 JDK1.8 为例,分析一下 ArrayList 的底层源码。
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851 ...