项目收获总结--MySQL的知识收获

news2024/11/17 14:33:27
一、概述

最近几天公司项目开发上线完成,做个收获总结吧~ 今天先记录MySQL的收获和提升。

二、MySQL表分区

项目中遇到数据量过大导致在查询过程中会出现各种超时的情况,当然是可以使用各种中间件比如MyCat,ShardingJDBC 等分库工具来进行分库分表,但在第一阶段做数据库设计时,可以使用MySQL自己的数据分区,暂不做分库操作。

2.1 MySQL数据分区

MySQL的数据分区(Partitioning)是数据库功能,允许将一个表物理地分成多个独立的、更小的、更易于管理的片段,这些片段被称为分区。每个分区在逻辑上都是表的一部分,但在物理存储上,每个分区可以有自己的存储引擎、文件、索引等。
使用分区的有点在于:

性能方面:对于某些查询,尤其是范围查询,分区可以显著提高性能,因为MySQL可以仅扫描需要的数据分区,而不是整个表。
管理方面:可以对单独的分区进行备份、删除或检查,这使得管理大型表变得更加容易。
归档方面:可以将旧数据移动到单独的分区,并轻松地从主表中删除这些分区,从而实现数据的归档。
2.2 MySQL分区方法

MySQL 支持多种分区方法,包括:

RANGE 分区:基于列值的范围进行分区。
LIST 分区:基于列值的列表进行分区。
HASH 分区:基于用户定义的表达式的返回值的哈希值进行分区。
KEY 分区:类似于 HASH 分区,但 MySQL 服务器提供哈希函数。
COLUMNS 分区:是 RANGE 和 LIST 分区的扩展,允许基于多个列的值进行分区。
2.2.1 RANGE分区
定义:基于属于一个给定连续区间的列值,把多行分配给分区。
用途:非常适合于基于时间范围的数据,如日志、交易记录等。
特点:分区键必须是整数、日期或日期时间类型。
     分区表必须至少包含一个RANGE分区。
     每个RANGE分区都定义了一个值的范围,如 PARTITION p0 VALUES LESS THAN (100)。
限制:不支持外键和全文索引。
2.2.2 LIST分区
定义:类似于RANGE分区,但它是基于列值匹配一个离散值集合中的某个值来进行选择。
用途:当数据可以按照某个离散值列表进行分组时,如地域、类别等。
特点:分区键可以是整数或枚举类型。定义时指定一个值列表,如 PARTITION p1 VALUES IN (1, 3, 5)。
限制:与RANGE分区类似,不支持外键和全文索引。
2.2.3 HASH分区
定义:基于用户定义的表达式的返回值来进行选择的分区,该表达式使用将要插入到表中的这些行的列值进行计算。
用途:当数据分布需要均匀或随机时,HASH分区可以确保数据在预先确定数目的分区中平均分布。
特点:分区键可以是任何MySQL中的有效表达式,只要它返回非负整数值。
     可通过指定分区数量来控制数据的分布。
限制:不支持外键和全文索引。
2.2.4 KEY分区
定义:类似于HASH分区,但KEY分区的哈希函数是由MySQL服务器提供。
用途:与HASH分区类似,但使用MySQL内部的哈希函数。
特点:分区键可以是一列或多列,但所有列都必须是整数类型。
     MySQL服务器会处理列的哈希值,并将数据分配到不同的分区。
限制:与HASH分区相同,不支持外键和全文索引。
2.2.5 COLUMNS分区
定义:MySQL 5.5及以上版本支持基于多个列的分区,这被称为COLUMNS分区。
用途:允许根据多列的值进行分区,提供了更大的灵活性。
特点:可以使用多个列作为分区键。
     支持RANGE和LIST分区。
限制:与上述分区类型类似的限制。
2.3 MySQL分区示例

假设有一个名为 sales 的表,用于记录销售数据,并且想基于 sale_date 列进行RANGE 分区并且按照每月交易数据分区,当然由于数据增加,是需要动态分区的。

CREATE TABLE sales (  
    sale_id  VARCHAR(100) NOT NULL, 
    sale_name VARCHAR(100) NOT NULL, 
    amount DECIMAL(10, 2) NOT NULL,  
    dsYear VARCHAR(20) NOT NULL
)  
PARTITION BY RANGE COLUMNS(dsYear) (  
    PARTITION p0 VALUES LESS THAN ('202404'),  
    PARTITION p1 VALUES LESS THAN ('202405'),  
    PARTITION p2 VALUES LESS THAN ('202406'),  
    PARTITION p3 VALUES LESS THAN ('202407')  
);

查看分区信息:在这里插入图片描述
动态新增分区需要定时任务在月末最后一天,执行SQL:

ALTER TABLE sales ADD PARTITION (partition p4 VALUES LESS THAN ('202408'))

在这里插入图片描述
要对分区表做查询需要增加分区查询条件,和分库是一样的,查询的时候需要命中分库规则,就不会进行全表的扫描。
先使用Navicat16自带的造数据的功能 或者 用存储过程来造数据:

CREATE DEFINER=`root`@`%` PROCEDURE `CreateTestData`()
BEGIN
    DECLARE v_counter INT DEFAULT 1;
    WHILE v_counter <= 1000000 DO
        INSERT INTO sales(sale_id, sale_name, amount,dsYear)
        VALUES(UUID_SHORT(), CONCAT('Data', v_counter), v_counter,'202407');
        SET v_counter = v_counter + 1;
    END WHILE;
END

通过普通查询来看一下查询速度:

SELECT * FROM sales WHERE sale_name = Data1';

在这里插入图片描述

再看下分区查询:

SELECT * FROM sales PARTITION (p3) WHERE sale_name = 'Data1'

在这里插入图片描述
共200w的数据查询速度的差距还是蛮明显。

2.4 注意事项
1)不是所有的存储引擎都支持分区。MyISAM 和 InnoDB 支持分区,但MEMORY存储引擎不支持。
(2)分区键必须是表的一个列或表达式的组合,且必须是整数类型、返回整数值的表达式或 DATE/DATETIME 列。
(3)分区表可能有一些限制和注意事项,例如,某些类型的索引可能不支持,或者某些查询优化可能不适用于分区表。因此,在决定使用分区之前,要先详细了解这些限制和注意事项。
三、MySQL回表

这个是在项目SQL优化中需要考虑的知识点,其他优化方式就不说啦,从索引覆盖聊起吧。

3.1 索引覆盖(覆盖索引)

数据库中的一种优化手段,当执行一个SQL查询时,如果只需要查询某几个字段的值,并且这几个字段的数据都已经被包含在某一个索引中(不是全表扫描),那么数据库引擎就会直接通过这个索引来取得数据,而无需再回表查询,从而极大减少I/O操作,提高查询效率。
索引覆盖的优点体现出:

1)减少I/O次数:因为通过覆盖索引可以直接获取数据,所以不需要再回表查询,从而减少I/O次数。
(2)提高查询速度:由于减少I/O操作,查询速度自然也得到提高。
(3)索引的选择性:选择性是指不重复的索引值与数据表的总记录数的比值。选择性越高,通过索引筛选出的数据就越少,从而提高查询效率。

这里就涉及到回表查询或者回表操作。

3.2 SQL回表

SQL回表是指在使用非聚簇索引(也称为辅助索引或二级索引)进行查询时,由于非聚簇索引中只存储索引字段的值和对应的主键(聚簇索引)键值,因此,如果需要获取非索引列的数据,则需要根据主键(聚簇索引)中的键值去查找实际的数据行。这个操作过程被称为回表。
其原理表现在:

非聚簇索引结构:非聚簇索引的叶子节点存储的是(索引列的值,主键的值)。

查询过程:当使用非聚簇索引进行查询时,首先通过非聚簇索引找到满足条件的主键键值。然后,根据这些主键键值,再回到聚簇索引(主键索引)中查找完整的数据行。

例如:
有一个用户表users,包含id(主键)、name和age三个字段,其中在name字段上建立非聚簇索引。
执行查询:

SELECT * FROM users WHERE name='Tom'

会发生回表。因为首先会通过name上的非聚簇索引找到满足条件的id,然后再根据这些id回到聚簇索引中查找完整的用户数据。
而查询:

SELECT id, name FROM users WHERE name='Tom'

不会回表,因为所需的数据都在非聚簇索引中可以找到。
而回表操作会增加I/O次数,从而可能影响查询性能。特别是在大表和复杂查询场景下,回表操作可能成为性能瓶颈,这也是在SQL中减少SELECT *的一个原因。
为减少回表操作,可以考虑将需要查询的字段加入到索引中,形成复合索引(也称为联合索引或覆盖索引)。这样,查询时就可以直接从索引中获取到需要的数据,而无需回表。所以,建立索引的时候,要非常注意,并不是说索引不好,而是说要会加索引。

3.3 索引最左匹配原则

由于建立索引大部分都不会只是单独的一个字段,所以就有复合索引。
最左匹配原则(Leftmost Prefix Rule) 主要是在使用复合索引(多列索引或多字段索引)时的一个关键理念。这个原则指出,当使用复合索引进行查询时,查询条件应该尽可能地从索引的最左边开始匹配,这样索引才能被有效地使用。

例如:有一个基于(last_name, first_name)的复合索引进行查询时,查询条件必须包含索引的最左边的一列或多列:

last_name:SELECT * FROM employees WHERE last_name = 'Smith';
last_name和first_name:SELECT * FROM employees WHERE last_name = 'Smith' AND first_name = 'John'; 

这两个查询可以有效地使用这个索引,因为符合按照复合索引的从左到右顺序写where条件。而对于查询:

first_name:SELECT * FROM employees WHERE first_name = 'John';

则不能有效地使用这个索引,因为它没有包含索引的最左边的列last_name。
创建复合索引时,列的顺序很重要。应该将最常用于查询条件的列放在索引的最左边。
例如:
如果经常基于last_name进行查询,但很少基于first_name进行查询,那么应该创建一个基于(last_name, first_name)的索引,而不是基于(first_name, last_name)的索引。

当然,并不必须始终遵循这个原则。在实际应用中,需要根据查询的需求和数据的分布来决定是否使用复合索引以及索引的列顺序。

四、前缀索引

使用前缀索引查询名称可以实现极佳的SQL优化,具体参考我另一篇帖子:
项目实战-MySQL极佳优化方案—前缀索引

五、MySQL索引失效场景

以下是我在项目中遇到的失效场景

5.1 联合索引不满足最左匹配原则

索引组成:

KEY `union_idx` (`id_no`,`username`,`age`)

SQL:

explain select * from t_user where id_no = '1002';
explain select * from t_user where id_no = '1002' and username = 'Tom2';

explain结果:
在这里插入图片描述
union_idx索引,但只用到了id_no列。而完全失效:

explain select * from t_user where username = 'Tom2' and age = 12;
explain select * from t_user where age = 12;
explain select * from t_user where username = 'Tom2';

在这里插入图片描述

5.2 使用select * 语句
5.3 索引列参与运算
explain select * from t_user where id + 1 = 2 ;

explain结果:
在这里插入图片描述
优化一下:

-- 内存计算,得知要查询的id为1
explain select * from t_user where id = 1 ;
-- 参数侧计算
explain select * from t_user where id = 2 - 1 ;
5.4 索引列参使用函数
explain select * from t_user where SUBSTR(id_no,1,3) = '100';

explain结果:
在这里插入图片描述

5.5 错误的Like使用
explain select * from t_user where id_no like '%00%';

explain结果:
在这里插入图片描述
模糊查询时(like语句),模糊匹配的占位符位于条件的首部索引失效,like 'abc%'就不会。

5.6 类型隐式转换
explain select * from t_user where id_no = 1002;
5.7 使用OR操作
explain select * from t_user where id = 2 or username = 'Tom2';
5.8 两列做比较
explain select * from t_user where id > age;
5.9 不等于比较
explain select * from t_user where id_no <> '1002';
5.10 is not null
explain select * from t_user where id_no is not null;
5.11 not in和not exists
explain select * from t_user where id in (2,3);
explain select * from t_user where id_no in ('1001','1002');
explain select * from t_user u1 where exists (select 1 from t_user u2 where u2.id  = 2 and u2.id = u1.id);
explain select * from t_user where id_no between '1002' and '1003';
5.12 order by导致索引失效(MySQL8.0.18版本除外)
explain select * from t_user order by id_no ;
5.13 参数不同导致索引失效
explain select * from t_user where create_time > '2024-07-05 09:04:23';

索引失效的特殊情况:MySQL优化器的其他优化策略,比如优化器认为在某些情况下,全表扫描比走索引快,则它就会放弃索引。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1900634.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何选择最佳的照片和视频恢复软件

您是否意外从硬盘或 USB 卡中删除了照片或视频&#xff1f;最好的视频和照片恢复软件可以帮到您&#xff01;如果您一直在寻找最好的照片恢复软件&#xff0c;那么您来对地方了。本文将分享一些帮助您找到最佳视频恢复软件的提示。 重要提示&#xff1a;事实&#xff1a;媒体文…

VirtualBox 安装 Ubuntu Server24.04

环境&#xff1a; ubuntu-2404-server、virtualbox 7.0.18 新建虚拟机 分配 CPU 核心和内存&#xff08;根据自己电脑实际硬件配置选择&#xff09; 分配磁盘空间&#xff08;根据自己硬盘实际情况和需求分配即可&#xff09; 设置网卡&#xff0c;网卡1 负责上网&#xff0c…

通过SDK使用百度智能云的图像生成模型SDXL

登录进入百度智能云控制台&#xff0c;在模型广场按照图像生成类别进行筛选&#xff0c;可以找到Stable-Diffusion-XL模型。点击Stable-Diffusion-XL模型的API文档后在弹出的新页面下拉可以找到SDK调用的说明。 import qianfandef sdxl(file: str, prompt: str, steps: int 2…

grpc-go服务端接口添加

【1】新建一个目录whgserviceproto&#xff0c;目录下新建一个proto包&#xff1a;whgserviceproto.proto &#xff08;注意目录和包名称保持一致&#xff09; //协议为proto3 syntax "proto3"; // 指定生成的Go代码在你项目中的导入路径 option go_package"…

Midjourney 预设

使用命令/settings 进入预设,根据点击不同选项来配置。 🌹 1. 设置工作所使用的模型版本。 1️⃣ MJ Version 1 2️⃣ MJ Version 2 3️⃣ MJ Version 3 4️⃣ MJ Version 4 5️⃣ MJ Version 5 5️⃣ MJ Version 5.1 🔧Raw Mode 🌈 Niji Version 4 🍎 Niji Versio…

CV04_PASCAL VOC2012数据集介绍

1.1 简介 PASCAL Visual Object Classes (VOC) 2012 数据集是计算机视觉领域中一个广泛使用的标准数据集&#xff0c;用于评估和促进对象识别、分类、目标检测、图像分割以及其他视觉理解任务的算法性能。PASCAL VOC项目起始于2005年&#xff0c;并且每年都会更新数据集&#…

【前端项目笔记】7 商品管理

商品管理 效果展示&#xff1a; 在功能开发之前&#xff0c;创建商品列表的子分支 git branch 查看所有分支 git checkout -b goods_list 创建并切换到新分支goods_list git push -u origin goods_list 将新分支goods_list推送到云端仓库origin并命名为goods_list保存 通过…

景色短视频:成都柏煜文化传媒有限公司

景色短视频&#xff1a;定格自然之美&#xff0c;邂逅心灵之旅 在这个被数字洪流包围的时代&#xff0c;短视频以其独特的魅力&#xff0c;为我们打开了一扇通往无限可能的大门。而在众多短视频类型中&#xff0c;景色短视频以其无与伦比的视觉冲击力&#xff0c;成为了许多人…

大模型周报|15 篇必读的大模型论文

大家好&#xff0c;今日必读的大模型论文来啦&#xff01; 1.谷歌推出风格感知拖放新方法 Magic Insert 来自谷歌的研究团队提出了 Magic Insert&#xff0c;用于以物理上可信的方式将用户提供的图像中的对象拖放到不同风格的目标图像中&#xff0c;同时与目标图像的风格相匹…

利用C语言实现三子棋游戏

文章目录 1.游戏界面2.游戏内容2.1 棋盘类型2.2棋盘的初始化2.3 打印棋盘的界面展示 3.游戏操作3.1 玩家操作3.2 电脑操作3.3 胜负判定 4.代码整合 1.游戏界面 无论写任何程序&#xff0c;我们都需要先去了解它的大概框架&#xff0c;这里我们先把它的初始界面写出来。一个游戏…

使用maven搭建一个SpingBoot项目

1.首先创建一个maven项目 注意选择合适的jdk版本 2.添加依赖 2.在pom.xml中至少添加依赖 spring-boot-starter-web 依赖&#xff0c;目的是引入Tomcat&#xff0c;以及SpringMVC等&#xff0c;使项目具有web功能。 <!-- 引入 包含tomcat&#xff0c;SpringMVC&#xff0c…

广州星启帆:点亮自闭症儿童康复之路的璀璨星辰

在广州这座充满温情的城市中&#xff0c;广州星启帆自闭症康复中心如同一颗璀璨的星辰&#xff0c;照亮了无数自闭症儿童及其家庭的前行之路。这家机构以“点亮希望&#xff0c;启航未来”为使命&#xff0c;向所有踏入这里的家庭承诺&#xff1a;我们将携手并肩&#xff0c;共…

springcloud分布式架构网上商城 LW +PPT+源码+讲解

3系统分析 3.1可行性分析 在开发系统之前要进行系统可行性分析&#xff0c;目的是在用最简单的方法去解决最大的问题&#xff0c;程序一旦开发出来满足了用户的需要&#xff0c;所带来的利益也很多。下面我们将从技术、操作、经济等方面来选择这个系统最终是否开发。 3.1.1技术…

el-scrollbar组件使用踩坑记录

一、el-scrollbar和浏览器原生滚动条一起出现 问题描述 el-scrollbar组件主要用于替换浏览器原生导航条。如下图所示&#xff0c;使用el-scrollbar组件后&#xff0c;发现未能成功替换掉浏览器原生导航条&#xff0c;二者同时出现。 引发原因 el-scrollbar的height属性如果…

怎样把自己电脑ip改成动态ip:步骤与解析

在今天的网络世界中&#xff0c;IP地址是计算机与互联网沟通的桥梁。而动态IP地址&#xff0c;作为其中的一种类型&#xff0c;由于其自动分配和管理的特性&#xff0c;为用户提供了更大的便利性和灵活性。那么&#xff0c;您是否想知道怎样将电脑IP改为动态呢&#xff1f;本文…

win11中配制了系统的环境变量mvn/java,但是mvn/java就是提示不存在的解决方法。

1、已经配制了环境变量&#xff0c;但是提示mvn不存在 2、然后我们在开始程序中查看到cmd&#xff0c;然后以管理员运行&#xff1a; 这样的话&#xff0c;是可以mvn这个命令的&#xff0c;而且只有这种方式是可以的&#xff0c;其它的方式&#xff0c;就算设置了以管理员身份运…

CSS 【详解】样式选择器(含ID、类、标签、通配、属性、伪类、伪元素、Content属性、子代、后代、兄弟、相邻兄弟、交集、并集等选择器)

CSS 样式选择器&#xff0c;用于选中页面中的 html 元素&#xff0c;以便添加 CSS 样式。 按渲染性能由高到低 依次是&#xff1a; ID 选择器 #id 通过元素的 id 属性选中元素&#xff0c;区分大小写 <p id"p1" >第一段</p>#p1{color: red; }但不推荐使…

mybatis-plus参数绑定异常

前言 最近要搞个发票保存的需求&#xff0c;当发票数据有id时说明是发票已经保存只需更新发票数据即可&#xff0c;没有id时说明没有发票数据需要新增发票&#xff1b;于是将原有的发票提交接口改造了下&#xff0c;将调用mybatis-plus的save方法改为saveOrUpdate方法&#xff…

Spring AOP、Spring MVC工作原理、发展演变、常用注解

Spring AOP 概念 AOP全称为Aspect Oriented Programming&#xff0c;表示面向切面编程。切面指的是将那些与业务无关&#xff0c;但业务模块都需要使用的功能封装起来的技术。 AOP基本术语 **连接点&#xff08;Joinpoint&#xff09;&#xff1a;**连接点就是被拦截到的程序执…