首页 > 数据库 >mysql在工作中遇到的

mysql在工作中遇到的

时间:2024-02-20 14:38:09浏览次数:31  
标签:... 索引 mysql 间隙 遇到 工作 sql 数据

一:数据类型

数据类型上踩到过一次坑,是因为sql的不规范写法的,在这之前确实没有注意到过平时的写法,就是在表结构上那一列字段类型是字符串的,然后在sql查询的时候是数字:

where  col1 = 1234;

这样子结果就导致了索引失效,这个是因为mysql的内部的执行计划导致的,我个人是这么理解的,就比如索引的失效条件中有一个是对索引的条件进行函数运算,然后在上面的sql ,因为字段类型是 字符串,然后where 后面是数字,那么mysql 就会自动的把数字转化为字符串(隐式加了函数),所以就导致了索引失效;


和他类似的也遇到过一个,那个是有关于$ 和 # 的问题,就是用到了mybaits,当时的sql大概是:

select ... from   where ...  order by #{}

这个#{} 真的是习惯性的写上去了,因为平时都这么写的,用在预编译上可以防止sql注入,结果当时用了之后发现order by 没有生效,一开始是没找到原因,sql 打印出来也没发现任何的问题,但就是排序失效

select ... from   where ...  order by 'age'

然后就是自己也手打了一遍的sql,发现在手打的sql 排序是有效果的

select ... from   where ...  order by age

仔细对比后发现是因为排序字段后面加了 引号,引号就是#{} 来预编译,后续改成了

select ... from   where ...  order by ${}

时间字段自动赋值:

关于updateTime /creatTime 这类自动赋值的字段,之前的时候我都是用mybatis-plus 来进行自动赋值的,有次我看到了别人没有配置自动填充,在业务代码里面也没有设置属性值,但就是自动更新了,然后查了一下,发现mysql 针对字段类型

DATETIME和 TIMESTAMP 有2个自动赋值的属性 DEFAULT CURRENT_TIMESTAMP 和 ON UPDATE

create table test (
      col1 DATETIME DEFAULT CURRENT_TIMESTAMP,
      col2 DATETIME ON UPDATE CURRENT_TIMESTAMP,
      col3 DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);

在上面col1 就可以创建的时候空的情况下设置个当前时间戳

col2 就可以在更新的时候更新最新的时间


然后就是关于字符集的,因为我之前都是这种的没出现过啥问题

image-20240220104424589

但是之前有遇到过一次,在老表上导入emoji表情的时候,发现导入不进去,格式不支持,后续就是改了该表的结构


二:锁

关于锁,主要是关于间隙锁,之前有遇到过一次情况就是因为间隙锁的产生从而引发了死锁问题,至于读锁写锁,共享锁等,因为没遇到过这方面的问题,所以暂时先不记录

1:间隙锁(cap lock)不锁记录 RR隔离级别

2:临建锁(next-key lock)锁住数据,以及数据前的间隙 RR隔离级别

临建锁可以理解为间隙锁+行锁

锁升级:

前提就是在默认的事务隔离级别下,Innodb会使用next-key (临键锁)进行扫描

1:遇到唯一索引的时候,如果是已经存在的记录进行等值匹配,那么临建锁会变成行锁,如果这条记录不存在,那么临建锁会变成间隙锁;

2:如果查询条件是没有通过索引的,那么会针对表的所有记录都行锁

3:常规的等值查询中,查询的条件左边为临建锁(锁自身和左边范围)后边为间隙锁(锁自身和右边范围)

比如在 需要查询的数据c 在 a ,b 之间,那么innodb加锁是 ==>(a,c] +(c,b) 也就是 锁住(a,b)

-----》 这个其实可以这么理解,因为是常规的索引,比如需要查询name = zs 的数据,但是常规索引不保证数据唯一,就有可能是在查询的时候,后续又会加入name = zs 的数据,所以需要对左右都要进行加锁

当初遇到的死锁问题就类似于条件3,当时的业务代码流程大概就是 先进行更新数据,然后再插入一条数据; 于是就出现了问题

1:事务A 先更新数据 5,此时锁住了数据 (3,7),因为只是常规索引,所以操作会把左右都加上间隙锁,但是3,7这2个数据没有被锁
2:事务B也进行了类似的操作,导致数据 (3,7)被锁,(因为间隙锁是可兼容的,就是共享锁,所以2个锁可以共存)
3:事务A又插入了数据6,此时因为存在着间隙锁,但是数据6是插入操作,插入操作会添加插入意向锁,插入意向锁遇到了间隙锁就会等待
4:事务B也进行了同样的操作,于是就出发了死锁,innodb底层对于死锁就会触发异常

ps:我在网上看到过一个关于并发的优化,就是在一个事务中如果是先用update,那么从用update开始就会直接上锁,然后如果是先用select,因为普通的select不会加锁,那么他锁的时间就会变短,就能提高效率

死锁排查sql(8.0.19)

-- 1、查看正在进行中的事务
SELECT * FROM information_schema.INNODB_TRX;
-- 2、查看正在锁的事务
SELECT * FROM performance_schema.data_locks;
-- 3、查看等待锁的事务
SELECT * FROM performance_schema.data_lock_waits;
-- 5、查看最近死锁的日志
show engine innodb status;
-- 查看当前正在进行中的进程
show processlist

三:索引

索引上,基本上遇到的问题就是索引添加的太多了,然后innodb内部是会自己选择索引的,选择的就不一定是最优解,所以可以进行指定索引

force index 这类的指定sql

遇到过几个特殊情况:

1: 2个表的编码风格不一样,就是一个是utf8 一个是utf8mb4 ,这就导致了索引失效

2:在订单表中有着商户id 和时间 作为索引,因为要统计一段时间下的商户嘛,然后就是mysql 选择的索引是时间索引,然后就是因为订单表中有很多的商户,有些大商户呢订单数量多,有些商户订单数量少,然后因为innodb他查询数据的话是一页一页加载到内存中进行匹配的,如果遇到了小商户,他订单少,然后innodb就得重复加载多次之后才能筛选到想要的数据,这就导致了小商户查询时间长,大商户查询时间短,这个时候就比较适合使用 联合索引

3: 这个就是听别人说起的了,因为我的话 删除数据都是用逻辑删除的,然后有人会使用物理删除嘛,然后因为mysql 在选择索引的时候会通过 show index 中的cardinal ,但是这个cardinal数据只会新增不会减少,也就是删除数据不会导致这个减少,因此 需要偶然使用analyze tables 来维护表数据

标签:...,索引,mysql,间隙,遇到,工作,sql,数据
From: https://www.cnblogs.com/zz0203/p/18022993

相关文章

  • MySQL 执行计划需要详细查看的内容
    1、id(重要):每一个select语句都会分配一个id。 id相同,从上到下执行 id不同,id越大,越先执行 id为null,不查询,仅表示一个结果集2、select_type(重要):查询类型 simple:简单查询,不包括子查询,union查询 primary:select查询字段列中存在子查询 union:存在union操......
  • 打开云服务器的MySQL数据库表很慢
    远程连接MYSQL速度慢,有时远程连接到MYSQL用时4-20秒不等,本地连接MYSQL正常。出现这种问题的主要原因是,默认安装的MYSQL开启了DNS的反向解析。解决方法:在my.ini(WINDOWS系统下)或my.cnf(UNIX或LINUX系统下)文件的[mysqld]下加入skip-name-resolve这一句。连接mysql速度慢的解决......
  • centos6设置mysql5.7开机自启
    环境:OS:Centos6db:mysql5.7 1.修改启动文件#!/bin/sh#CopyrightAbandoned1996TCXDataKonsultAB&MontyProgramKB&DetronHB#ThisfileispublicdomainandcomeswithNOWARRANTYofanykind#MySQLdaemonstart/stopscript.#Usuallythisi......
  • 解锁Mysql中的JSON数据类型,怎一个爽字了得
    引言在实际业务开发中,随着业务的变化,数据的复杂性和多样性不断增加。传统的关系型数据库模型在这种情况下会显得受限,因为它们需要预先定义严格的数据模式,并且通常只能存储具有相同结构的数据。而面对非结构化或半结构化数据的存储和处理需求,选择使用非关系型数据库或者创建子表存......
  • 软件测试/人工智能|熟练使用web控件定位技巧,提升测试工作效率!
    简介在做Web自动化时,最根本的就是操作页面上的元素,首先要能找到这些元素,然后才能操作这些元素。工具或代码无法像测试人员一样用肉眼来分辨页面上的元素。那么要如何定位到这些元素,本章会介绍各种定位元素的方法。web控件定位id定位Python实现driver.find_element(By.I......
  • Kob_配置Mysql与注册登录模块(中)
    配置Mysql与注册登录模块(中)session与jwtsession验证url包括公开的和需要权限的登录,注册这种页面肯定是公开界面,大家都可以访问.发送一个登录请求,将账号和密码发送到服务器,服务器接收数据去和数据库存储的账号密码数据进行比对,如果通过就向用户发送一个sessionid,用户会将这......
  • Docker 使用遇到的问题解决 更改Tag
    dockertagconsul:1.15.4consul:latestdockerrmiconsul:1.15.4删除制定版本在运行时,有些镜像拉取时报错我这里 时 consu,只能制定版本下载1.15.4Errorresponsefromdaemon:manifestforconsul:latestnotfound:manifestunknown:manifestunknown ......
  • MySQL 零碎笔记2
    1.分区表适用场景:业务简单,单表查询,且都跟时间范围查询相关。数据需要定期清理数据,无需保留全部数据。数据更新频率较低,只有写入操作。优点:查询条件包含分区条件时,可以直接扫描必要的分区。也可以直接指定必要的分区来提高查询效率。聚合查询时,可以很容易地在每个分区上并行......
  • springboot整合activiti工作流(源码及功能分析)
    前言activiti工作流引擎项目,企业erp、oa、hr、crm等企事业办公系统轻松落地,一套完整并且实际运用在多套项目中的案例,满足日常业务流程审批需求。一、项目形式springboot+vue+activiti集成了activiti在线编辑器,流行的前后端分离部署开发模式,快速开发平台,可插拔工作流服务。工作......
  • 一例MySQL的insert死锁
    原文链接:https://fanyilun.me/2022/03/09/%E4%B8%80%E4%BE%8BMySQL%E7%9A%84insert%E6%AD%BB%E9%94%81/ 分享一个最近遇到的一例MySQL死锁。关于MySQL的锁,几年前写过一篇原理类的文章,基础知识建议移步MySQL加锁分析。背景  我们使用MySQL实现了一个通用的分布式DB锁,建表语句......