红黑树-Java实现

article/2025/10/1 4:01:03

目录

一、定义

二、插入

 三、删除

四、全部代码

 五、颜色效果


一、定义

红黑树是特殊的平衡二叉树,具有以下特性:

1、根节点的颜色是黑色

2、节点颜色要么是黑色、要么是红色

3、如果一个节点的颜色是红色,则它的子节点必须是黑色,即不能有2个连续的红色节点

4、每个叶子节点都是黑色(这里的叶子节点是为空的叶子节点)

5、从一个节点到该节点的叶子节点的所有路径上都包含相同数量的黑色节点

       通过上面的定义,可以看到红黑树本质上还是一颗二叉查找树,所以,对红黑树的插入删除操作都可以分为两阶段来完成,首先,将红黑树看成一颗普通的二叉查找树完成插入删除操作,然后,通过旋转(左旋、右旋)以及颜色调整来使得操作后的树满足红黑树的所有特性即可。

二、插入

说明:以下的讨论,在如下前提下进行:插入的节点为S(son),S的父亲节点为F(father),F的父亲节点为G(grandfather),而F的兄弟节点为U(uncle),并且F为G的左儿子。(F为G的右儿子对称操作即可

Step 1:执行二叉搜索树插入逻辑

Step 2:将插入的节点着色为红色

    我们希望这次插入尽可能不破坏红黑树的性质,这样我们就可以不用进行额外的调整操作!所以,根据特性(5),我们显然不能将节点涂成黑色,因为这样所有经过点S的路径的黑色节点都多了一个,就破坏了特性(5),所以我们将S的颜色首先着色为红。

Step 3:进行适当得旋转以及颜色调整

如果插入节点的父节点是红,那么违反了特性(3),所以需要进行调整,共有三个case

case 1:F为红,U为红

操作:将F以及U设置为黑,G设为红,并将G看成新插入的节点(即下一轮的S),递归操作

原因:这个操作实际是想将红色往根处移动。将红色往上移了一层,并不会打破红黑树的特性,不断的把红色往上移动,当移动到根时,直接将根设置为黑色,就完全符合红黑树的性质了。
这里写图片描述

 case 2:F为红,U为黑,并且,S为F的右儿子

操作:将F左旋,并把F看成新加入的节点(即下一轮的S),继续后面的判断

原因:这个操作是为了将这一case转换为case 3

这里写图片描述

 case 3:F为红,U为黑,并且,S为F的左儿子

操作:先将F设为黑,G设为红,然后G右旋。这样操作后,就完全符合红黑树的性质

原因:G与F颜色互换,对左边路并没有影响,不过,对于右边路来说,由于G变为了红,其实少了一个黑,因此,将G右旋,使得黑色的F变为新的G,这样,就为右边路加回去了一个黑,而左边路只是损失了一个红,并不影响红黑树的平衡,这样操作后将会完全符合红黑树的性质,之所以说是完全符合,因为原来G的地方是个黑色节点,后来用了黑色的F去代替了G,对于G往上的层来说,并没有发生颜色变化,自然就是平衡的,所以,经过这一步的操作,红黑树恢复所有特性。

这里写图片描述

 三、删除

说明:S的父亲节点为P,S的兄弟节点为B,B的左儿子为BL,B的右儿子为BR,且S为P的左儿子。(S为P的右儿子对称操作即可

step 1:进行二叉查找树的删除操作
    我们假设想要删除的节点是X,找到的替代节点为Y(选择方式是X的右子树的最小点),那么我们可以将Y的值拷贝到X,然后将这个Y删除,将Y删除,也会需要有一个人顶替现在的Y的位置,我们设为S,接下来的讨论就会围绕着S展开。

step 2:红黑树性质判断
    由于我们将Y删除了,并且用S代替了Y的位置,如果Y原来是红色的,那么并不会破坏红黑树的颜色平衡,我们不需要额外的操作,删除成功!如果Y是黑色的,那么相当于经过Y的路径(现在是经过S)都会少了一个黑。那么我们怎么把这个黑弥补回来呢?那就是给S再加上一个黑,用来弥补删除Y而损失的那个黑。这时候,相当于S节点拥有了两个颜色,违反了特性(2),所以,我们现在想办法把这个多出来的黑色删除掉!
    如果原来S是红色的,那么我们直接不要S的红色,将S设置为黑色即可,因为丢弃红色是不会打破红黑树的颜色平衡的,我们这一操作是安全的。可是,如果S原来就是黑色呢?那就要看S是不是根了,如果是根,将黑色丢弃了也没啥,相当于所有的路径都减少了一个黑,也是不影响平衡的,最糟糕的情况在于S原来是黑,且不是根,这时候,我们就要进行一些旋转以及颜色调整来恢复红黑树的特性了!

step 3:旋转以及颜色调整

共有四个case:

Case 1: S是“黑+黑”,且B为红
操作:将P设为红,B设为黑,然后将P左旋,这时S获得了新的B,用新的B进行后续的判断

原因:在这种情况下,我们可以得到P必定为黑,并且BL & BR 也都为黑。由于我们想要左旋(左旋的目的是让S有新的B,从而转化为后面的case 2 or 3 or 4,进行下一步的操作),而又不能破坏红黑树的平衡,所以,将P设为红,B设为黑。
这里写图片描述

 Case 2:S是“黑+黑”,且B为黑,并且BL BR也都是黑

操作:将B设为红,并且让P为新的S,进行新一轮的递归

 原因:我们的目的就是想让多余的黑往上走,这时候,把这个多余的黑给到P,左边路的黑是不变的,而右边路多了一个,为了平衡,恰好BL BR都是黑,所以我们直接把B设为红就好啦,这样,黑就上浮到了P,将P看作新的起点(S),递归后面的操作就好啦~!

这里写图片描述

 Case 3:S是“黑+黑”,且B为黑,并且BL为红,BR为黑

操作:将B设为红,BL设为黑,然后B右旋

原因:这个操作是为了转换到case 4。B和BL的颜色互换也是为了平衡。
这里写图片描述

Case 4:S是“黑+黑”,且B为黑,并且BR为红,(P、BL任意颜色)

操作:将P的颜色给到B,将P设为黑,将BR设为黑,对P左旋,最后将S设置为root以结束循环。 

原因:我们将P的颜色给到B,然后将P左旋,这时候,不管P初始是什么颜色,首先是BL变成了P的儿子,而这里我们不关心BL的颜色,所以,必须要把P设置为黑色,这样即使BL为红色也不会破坏红黑树,而将P设置为黑色,对于左边路,都多了一个黑色,为了保证颜色平衡,正好把S中多余的那个黑丢掉啦。还有一点,不管P的初始颜色,左旋之后,右边路少了一个黑,为了补回来,我们让BR由红变黑就好啦!
这里写图片描述

 (注:蓝色表示任意颜色

四、全部代码

红黑树节点

package com.mzp.tree.rb;/*** 红黑树节点*/
public class RedBlackTreeNode {public static boolean Red = false;public static boolean Black = true;//节点颜色private boolean color;private int data;private RedBlackTreeNode left;private RedBlackTreeNode right;private RedBlackTreeNode parent;public RedBlackTreeNode(int data){this.data = data;color = Red;}public boolean isColor() {return color;}public void setColor(boolean color) {this.color = color;}public int getData() {return data;}public void setData(int data) {this.data = data;}public RedBlackTreeNode getLeft() {return left;}public void setLeft(RedBlackTreeNode left) {this.left = left;}public RedBlackTreeNode getRight() {return right;}public void setRight(RedBlackTreeNode right) {this.right = right;}public RedBlackTreeNode getParent() {return parent;}public void setParent(RedBlackTreeNode parent) {this.parent = parent;}
}

红黑树

package com.mzp.tree.rb;import java.util.LinkedList;
import java.util.Queue;/*** 红黑树*/
public class RedBlackTree {//根节点private RedBlackTreeNode root;public static void main(String[] args) {RedBlackTree tree = new RedBlackTree();tree.insert(12);tree.insert(1);tree.insert(9);tree.insert(2);tree.insert(0);tree.insert(11);tree.insert(7);tree.insert(19);tree.insert(4);tree.insert(15);tree.insert(18);tree.insert(5);tree.insert(14);tree.insert(13);tree.insert(10);tree.insert(16);tree.insert(6);tree.insert(3);tree.insert(8);tree.insert(17);tree.delete(12);tree.delete(1);tree.delete(9);tree.delete(2);tree.delete(0);tree.delete(11);tree.delete(7);tree.delete(19);tree.delete(4);tree.delete(15);tree.delete(18);tree.delete(5);tree.delete(14);tree.delete(13);tree.delete(10);tree.delete(16);//tree.delete(6);//tree.delete(3);//tree.delete(8);//tree.delete(17);System.out.println("层级");levelTraversal(tree.root);System.out.println();System.out.println("前序");recursivelyPreTraversal(tree.root);System.out.println();System.out.println("中序");recursivelyInTraversal(tree.root);System.out.println();System.out.println("后序");recursivelyPostTraversal(tree.root);}/*** 插入节点* @param data* @return*/public RedBlackTreeNode insert(int data){RedBlackTreeNode insert = new RedBlackTreeNode(data);if(root == null){root = insert;setBlack(insert);}else{RedBlackTreeNode parent = null;RedBlackTreeNode node = root;while(node != null){parent = node;if(node.getData() >= data){//左子树node = node.getLeft();}else{//右子树node = node.getRight();}}//跳出循环则说明找到插入位置if(parent.getData() >= data){parent.setLeft(insert);}else{parent.setRight(insert);}insert.setParent(parent);//旋转和调整节点颜色保持红黑树平衡insertFix(insert);}return insert;}/*** 旋转和调整节点颜色保持红黑树平衡* @param node 插入节点*/private void insertFix(RedBlackTreeNode node) {while(node.getParent() != null && isRed(node.getParent())){RedBlackTreeNode parent = node.getParent();RedBlackTreeNode grandFather = parent.getParent();if(grandFather.getLeft() == parent){//F为G左儿子的情况RedBlackTreeNode uncle = grandFather.getRight();if(uncle != null && isRed(uncle)){setBlack(parent);setBlack(uncle);setRed(grandFather);node = grandFather;continue;}if(parent.getRight() == node){//插入节点为父节点的右子树//左旋leftRotate(parent);//将旋转后的parent看作插入节点RedBlackTreeNode tmp = node;node = parent;parent = tmp;}setBlack(parent);setRed(grandFather);rightRotate(grandFather);break;}else{//F为G的右儿子的情况,对称操作RedBlackTreeNode uncle = grandFather.getLeft();if(uncle != null && isRed(uncle)){setBlack(parent);setBlack(uncle);setRed(grandFather);node = grandFather;continue;}if(parent.getLeft() == node){//插入位置为父节点的左子树//右旋rightRotate(parent);RedBlackTreeNode tmp = node;node = parent;parent = tmp;}setBlack(parent);setRed(grandFather);leftRotate(grandFather);break;}}setBlack(root);}/*** 删除节点* @param data* @return*/public RedBlackTreeNode delete(int data){RedBlackTreeNode node = query(data);if(node == null){return null;}deleteNode(node);return node;}/*** 查询节点* @param data* @return*/public RedBlackTreeNode query(int data){if(root == null){return null;}RedBlackTreeNode node = root;while(node != null){if(node.getData() == data){return node;}else if(node.getData() >= data){node = node.getLeft();}else {node = node.getRight();}}return null;}private void deleteNode(RedBlackTreeNode node) {if (node == null){return;}//替换节点RedBlackTreeNode replaceNode = null;if(node.getLeft() != null && node.getRight() != null){//存在左右子树RedBlackTreeNode tmp = node.getRight();while(tmp != null){replaceNode = tmp;tmp = tmp.getLeft();}//将替换节点的值放到原本需要删除的节点node.setData(replaceNode.getData());//删除替换节点node = replaceNode;}if(node.getLeft() != null){replaceNode = node.getLeft();}else{replaceNode = node.getRight();}RedBlackTreeNode parent = node.getParent();if(parent == null){root = replaceNode;if(replaceNode != null){replaceNode.setParent(null);}}else{if(parent.getLeft() == node){parent.setLeft(replaceNode);}else{parent.setRight(replaceNode);}if(replaceNode != null){replaceNode.setParent(parent);}}if(isBlack(node)){//replaceNode为了保持平衡,多了一个黑色,需修复removeFix(parent, replaceNode);}}/*** 修复* @param parent* @param node 多了一个黑色*/private void removeFix(RedBlackTreeNode parent, RedBlackTreeNode node) {while(isBlack(node) && node != root){if(parent.getLeft() == node){//S是P的左儿子RedBlackTreeNode brother = parent.getRight();if(isRed(brother)){setBlack(brother);setRed(parent);leftRotate(parent);brother = parent.getRight();}if(brother == null || (isBlack(brother.getLeft()) && isBlack(brother.getRight()))){setRed(brother);node = parent;parent = node.getParent();continue;}if(isRed(brother.getLeft()) && isBlack(brother.getRight())){setRed(brother);setBlack(brother.getLeft());rightRotate(brother);brother = parent.getRight();}brother.setColor(parent.isColor());setBlack(parent);setBlack(brother.getRight());leftRotate(parent);node = root;}else{//S是P的右儿子RedBlackTreeNode brother = parent.getLeft();if(isRed(brother)){setBlack(brother);setRed(parent);rightRotate(parent);brother = parent.getLeft();}if(brother == null || (isBlack(brother.getLeft()) && isBlack(brother.getRight()))){setRed(brother);node = parent;parent = node.getParent();continue;}if(isRed(brother.getRight()) && isBlack(brother.getLeft())){setBlack(brother.getRight());setRed(brother);leftRotate(brother);brother = parent.getLeft();}brother.setColor(parent.isColor());setBlack(parent);setBlack(brother.getLeft());rightRotate(parent);node = root;}}if(node != null){setBlack(node);}}/*** 左旋* @param node*/private void leftRotate(RedBlackTreeNode node) {RedBlackTreeNode right = node.getRight();RedBlackTreeNode parent = node.getParent();node.setRight(right.getLeft());if(right.getLeft() != null){right.getLeft().setParent(node);}node.setParent(right);right.setLeft(node);if(parent == null){root = right;right.setParent(null);}else{right.setParent(parent);if(parent.getLeft() != null && parent.getLeft() == node){parent.setLeft(right);}else{parent.setRight(right);}}}/*** 右旋* @param node*/private void rightRotate(RedBlackTreeNode node) {RedBlackTreeNode left = node.getLeft();RedBlackTreeNode parent = node.getParent();node.setLeft(left.getRight());if(left.getRight() != null){left.getRight().setParent(node);}node.setParent(left);left.setRight(node);if(parent == null){root = left;left.setParent(null);}else{left.setParent(parent);if(parent.getLeft() != null && parent.getLeft() == node){parent.setLeft(left);}else{parent.setRight(left);}}}/*** 设置颜色为黑* @param node*/public static void setBlack(RedBlackTreeNode node) {if(node == null){return;}else{node.setColor(RedBlackTreeNode.Black);}}/*** 设置颜色为红* @param node*/public static void setRed(RedBlackTreeNode node) {if(node == null){return;}else{node.setColor(RedBlackTreeNode.Red);}}/*** 是否是黑色节点* @param node* @return*/public static  boolean isBlack(RedBlackTreeNode node){if(node == null){return true;}else{return node.isColor() == RedBlackTreeNode.Black;}}/*** 是否是红色节点* @param node* @return*/public static  boolean isRed(RedBlackTreeNode node){if(node == null){return false;}else{return node.isColor() == RedBlackTreeNode.Red;}}/*** 层级遍历* @param root*/public static void levelTraversal(RedBlackTreeNode root){if(root == null){return;}Queue<RedBlackTreeNode> queue = new LinkedList<>();queue.offer(root);while(!queue.isEmpty()){RedBlackTreeNode poll = queue.poll();String color = "Black";if(isRed(poll)){color = "Red";}System.out.print(poll.getData()+"(" + color + ") ");if(poll.getLeft() != null){queue.offer(poll.getLeft());}if(poll.getRight() != null){queue.offer(poll.getRight());}}}/*** 前序遍历* @param node*/public static void recursivelyPreTraversal(RedBlackTreeNode node){if(node == null){return;}String color = "Black";if(isRed(node)){color = "Red";}System.out.print(node.getData()+"(" + color + ") ");recursivelyPreTraversal(node.getLeft());recursivelyPreTraversal(node.getRight());}/*** 中序遍历* @param node*/public static void recursivelyInTraversal(RedBlackTreeNode node){if(node == null){return;}recursivelyInTraversal(node.getLeft());String color = "Black";if(isRed(node)){color = "Red";}System.out.print(node.getData()+"(" + color + ") ");recursivelyInTraversal(node.getRight());}/*** 后序遍历* @param node*/public static void recursivelyPostTraversal(RedBlackTreeNode node){if(node == null){return;}recursivelyPostTraversal(node.getLeft());recursivelyPostTraversal(node.getRight());String color = "Black";if(isRed(node)){color = "Red";}System.out.print(node.getData()+"(" + color + ") ");}
}

 五、颜色效果

可参考根据红黑树研究记录-实例 - Geek_Ma - 博客园图片验证代码是否正确

 参考地址:红黑树理解以及Java实现_一个默默努力的人的博客-CSDN博客_红黑树java

红黑树研究记录-实例 - Geek_Ma - 博客园


http://chatgpt.dhexx.cn/article/JTL3LInf.shtml

相关文章

红黑二叉树原理分析

1.引言 HashMap的基本结构是数组&#xff0c;链表和红黑树。以数组为基本形态&#xff0c;数组中的元素先以链表形式储存&#xff0c;当链表的长 度超过8时&#xff08;包含数组上的那个链表头&#xff09;就会将链表转换为红黑树&#xff0c;以加快修改和查询效率。当然除了H…

理解红黑树及代码实现

1.红黑树定义 红黑树是一颗 红-黑的平衡二叉树,它具有二叉树的所有特性,是一颗自平衡的排序二叉树.(树中任何节点值都大于左子节点的值&#xff0c;而且都小于右子节点的值),其检索效率高&#xff0c;它是一颗空树或它的左右两个子树高度差的绝对值不超过1&#xff0c;并且左右…

红黑二叉树的漫画讲解(轻松理解红黑二叉树原理)

———————————— 二叉查找树&#xff08;BST&#xff09;具备什么特性呢&#xff1f; 1.左子树上所有结点的值均小于或等于它的根结点的值。 2.右子树上所有结点的值均大于或等于它的根结点的值。 3.左、右子树也分别为二叉排序树。 下图中这棵树&#xff0c;就是…

Java的二叉树、红黑树、B+树

数组和链表是常用的数据结构&#xff0c;数组虽然查找快&#xff08;有序数组可以通过二分法查找&#xff09;&#xff0c;但是插入和删除是比较慢的&#xff1b;而链表&#xff0c;插入和删除很快&#xff08;只需要改变一些引用值&#xff09;&#xff0c;但是查找就很慢&…

二叉树与红黑树

二叉树的形成 二叉树是n(n>0)个结点的有限集合&#xff0c;该集合或者为空集&#xff08;称为空二叉树&#xff09;&#xff0c;或者由一个根结点和两棵互不相交的、分别称为根结点的左子树和右子树组成 二叉树特点 由二叉树定义以及图示分析得出二叉树有以下特点&#xff1…

红黑树(C++实现)

文章目录 红黑树的概念红黑树的性质红黑树结点的定义红黑树的插入红黑树的验证红黑树的查找红黑树的删除红黑树与AVL树的比较 红黑树的概念 红黑树是一种二叉搜索树&#xff0c;但在每个结点上增加了一个存储位用于表示结点的颜色&#xff0c;这个颜色可以是红色的&#xff0c;…

红黑二叉树详解及理论分析

发表于我的博客网站(prajna.top)&#xff1a; http://prajna.top/doc/2/175 什么是红-黑二叉树&#xff1f; 红-黑二叉树首先是一颗二叉树&#xff0c;它具有二叉树的所有性质&#xff0c;是一种平衡二叉树。普通二叉树在生成过程中&#xff0c;容易出现不平衡的现象&#xff…

二叉树到红黑树

二叉树查找树 又叫二叉排序树。二叉查找树或者是一棵空树&#xff0c;或者是一棵具有如下性质的二叉树&#xff1a; 对于任何一个结点X若它的左子树非空&#xff0c;则左子树上所有结点的值均小于等于X的值&#xff1b;若它的右子树非空&#xff0c;则右子树上所有结点的值均大…

详解c++---红黑二叉树的原理和实现

目录标题 什么是红黑二叉树树红黑树的性质红黑树的效率分析红黑树的准备工作红黑树的insert函数节点的调整情况一情况二情况三 转换的实现打印函数find函数检查函数 什么是红黑二叉树树 avl树是通过控制平衡因子来控制二叉搜索树的平衡&#xff0c;当某个节点的平衡因子等于2或…

红黑树和二叉树有什么区别?

红黑树和二叉树有什么区别&#xff1f; 什么是二叉树&#xff1f;什么是红黑树&#xff1f; 二叉树&#xff08;Binary Tree&#xff09;是指每个节点最多只有两个分支的树结构&#xff0c;即不存在分支大于 2 的节点&#xff0c;二叉树的数据结构如下图所示 这是一棵拥有 6 …

二叉树系列:红黑树

介绍 红黑树(Red-Black Tree&#xff0c;简称R-B Tree)&#xff0c;它一种特殊的二叉查找树。红黑树是特殊的二叉查找树&#xff0c;意味着它满足二叉查找树的特征&#xff1a;任意一个节点所包含的键值&#xff0c;大于等于左孩子的键值&#xff0c;小于等于右孩子的键值。除了…

红黑树结构原理的图文讲解(非代码)

1.引言 HashMap的基本结构是数组&#xff0c;链表和红黑树。以数组为基本形态&#xff0c;数组中的元素先以链表形式储存&#xff0c;当链表的长度超过8时&#xff08;包含数组上的那个链表头&#xff09;就会将链表转换为红黑树&#xff0c;以加快修改和查询效率。当然除了Ha…

二叉树与红黑树见解

目录 一、红黑树简介二、 红黑树的特性三、红黑数的应用四、红黑树的原理实现4.1 识别红黑树4.2 红黑树节点的旋转4.3 插入节点4.3.1分情况讨论&#xff1a;4.3.2 代码示例 4.4删除节点相关引用 一、红黑树简介 红黑树是一种自平衡的二叉查找树&#xff0c;是一种高效的查找树…

什么是红黑树(内存最优的二叉树)

一.红黑树定义 红黑树(Red Black Tree) 是一种自平衡二叉查找树&#xff0c;是在计算机科学中用到的一种数据结构&#xff0c;典型的用途是实现关联数组。 它是在1972年由Rudolf Bayer发明的&#xff0c;当时被称为平衡二叉B树(symmetric binary B-trees)。后来&#xff0c;在1…

【二叉树进阶】红黑树(Red Black Tree) - 平衡二叉搜索树

文章目录 一、红黑树的概念二、红黑树的性质2.1 红黑树和AVL树效率对比 三、红黑树的结构&#xff08;KV模型&#xff09;四、红黑树的插入4.1 插入节点4.2 平衡化操作&#xff08;难点&#xff09;4.2.1 情况一4.2.2 情况二4.2.3 情况三 4.3 总结 五、红黑树的验证六、红黑树的…

MySQL 慢查询日志导入 Elasticsearch 可视化查询分析

当应用程序后台 SQL 查询慢的时候我们一般第一时间会查看数据库慢查询记录&#xff0c;但是慢查询记录是原始文本&#xff0c;直接查询搜索分析比较费时费力&#xff0c;虽然业界有针对 MySQL 慢查询分析的命令行工具&#xff08;比如&#xff1a;pt-query-digest&#xff09;&…

MySQL 慢查询日志如何查看及配置

简介 MySQL 慢查询日志是排查问题 SQL 语句&#xff0c;以及检查当前 MySQL 性能的一个重要功能。 查看是否开启慢查询功能&#xff1a; 说明&#xff1a; slow_query_log 慢查询开启状态 slow_query_log_file 慢查询日志存放的位置&#xff08;这个目录需要MySQL的运行帐号的…

MySQL高级篇——聊聊MySQL的慢查询日志

文章目录&#xff1a; 1.数据库服务器的优化步骤 2.查看系统性能参数 3.定位执行慢的 SQL&#xff1a;慢查询日志 4.查看 SQL 执行成本&#xff1a;SHOW PROFILE 1.数据库服务器的优化步骤 当我们遇到数据库调优问题的时候&#xff0c;该如何思考呢&#xff1f;这里把思考…

清理mysql慢查询日志_MySQL清理慢查询日志slow_log的方法

一、清除原因 因为之前打开了慢查询,导致此表越来越大达到47G,导致磁盘快被占满,使用xtrabackup进行备份的时候文件也超大。 mysql> show variables like log_output%; Connection id: 1694401091 Current database: mysql +---------------+-------+ | Variable_name | …

mysql 慢查询日志的设置与优化

目录 1 引言 2 慢查询日志配置 3 分析工具 1 引言 MySQL数据中有记录慢查询的一种手段。并且是MySQL自带的。可用来排查那些查询sql语句执行得慢。从而给开发者提供一个调优得依据。 MySQL 慢查询的相关参数解释&#xff1a; slow_query_log &#xff1a;是否开启慢查…