mysql刨根问底

2024-03-27 11:12
文章标签 mysql database 刨根问底

本文主要是介绍mysql刨根问底,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

索引:排好序的数据结构

二叉树:

红黑树

hash表:

b-tree:

   叶子相同深度,叶节点指针=空,索引元素不重复,从左到右递增排序

   节点带data

b+tree:

   非叶子节点只存储索引,可放更多索引

   叶子节点含all索引 用指针双向连接,提高区间访问性能

页大小16kb,2000w 高度3   3次磁盘io

   根节点常驻内存,减少磁盘io

引擎

innodb

    frm:           ibd:

   表数据文件本身按b+tree组织多索引结构文件

   聚集索引-叶节点含完整数据

myisam:索引/数据文件分离

    frm。 MYD。 MYI

    主键b+tree存储 data是地址引用,非聚集

explain少不了这个大佬

type关联类型或访问类型 

  mysql如何查找表中的行,system const  eq_ref  ref  range  index  all

  null:mysql在优化阶段分解查询语句,执行阶段不需要访问表 索引

  system,const:查询某部分优化并将其转化成一个常量

  eq_ref:primary key或unique_key 索引的all部分被连接使用,最多只会返回一条符合条件的记录

  ref:没有用唯一索引

不走索引:

   引擎本身不支持索引

   不等于 

   is null / is not null

   like 通配符: select 查询具体的列 

   复杂函数

   字符串不加单引号:类型转换

   or / in 查询时  不一定用索引,检索比例 表大小等因素不一定用索引

   范围查询优化

索引(a,b,c)

where a = 4 and b like 'kk%' and c=6;  //使用abc

where a = 4 and b like 'k%kk%' and c=7; //使用ab c

索引下推5.6后

trace工具:命令行打开 

  影响性能,分析执行计划

   sql准备阶段  格式化sql   

   sql优化阶段:去掉无意义语句

优化

order by与group by

 最左前缀法则,中间字段不能断

 using filesort 标识没走索引,order by * asc ,* desc  索引排序方式不同8后降序索引可以支持

  • using index指mysql扫描索引本身完成排序 效率高, filesort效率低没有用索引
  • order by使用索引最左前列 / where与order by条件组合满足索引最左前列
  •  尽量在索引列上完成排序,遵循索引建立时最左前缀法则
  • order by的条件不在索引列上,会产生using filesort
  • group by与order by类似,先排序后分组,索引创建顺序最左前缀法则
  • group by不需要排序可加group by null禁止排序

where 高于having,能写where中的限定条件就不要去having限定

filesort 文件排序

 单路排序:一次性取出满足条件的字段,sort buffer (1M)排序;trace看sort_mode显示sort_key additional_fields 或 sort_key,packed_additional_fields

 双路排序:回表排序,据相应条件取出排序字段和可直接定位的行数id,sort buffer排序,再次取需要的字段

  字段总长度 < max_length_for_sort_data,单路排序

  字段总长度 > max_length_for_sort_data,双路排序

索引设计原则

代码先行,索引后上

联合索引尽量覆盖

小基数字段不建索引:重复值少

长字符串前缀索引,order by和group by 中不能用

where与order by冲突时优先where

执行小表驱动大表

left  join左表驱动表  right join右边驱动表

   NLJ: 循环驱动表 读取关联字段  取出另一张被驱动表满足条件的数据,扫描磁盘

   BNL:驱动表数据读到join buffer中,被驱动表每一行取出与join buffer对比

   straight_join t1 on t2.a=t1.a 强制指定驱动表

      被驱动表的关联字段无索引的关联查询,BNL ;有索引NLJ

in:B表的数据集小于a表,in 优先exists

     select * from A where id in(select id from B);

exists当A表数据小于B,exists优先in

     select* from A where exists (select 1 from B where B.id=A.id)

count(*)  count(1)> count(字段) > count(id) 

  字段有索引:二级索引 ,比主键索引大小要小

  count(1) count(字段) 执行过程类似,count(1)不需要取字段

  count(*)做了优化,不取值 按行累加 效率高

查询mysql自己维护总行数

   myisam维护总行数,innodb不会存储总行数

show table status可查询表总行数

整型无负数,unsigned可扩大一倍

tinyint代替enum bitenum set

避免使用整数的显示宽度:不要int(10) 直接int,10是显示长度

decimal注意设置长度,精确计算

整形运算 存储实数:实数乘以相应的倍数后再操作

整数通常是最佳的数据类型:速度快 auto_increment

 myisam查询自动加给表读锁,改增删自动给涉及表加写锁

乐观锁:版本对比 CAS /   悲观锁:

表锁/页锁

行锁:

  索引上加锁,

  RR升级表锁需要解决不可重复读 (扫描过的索引被其他修改)

     幻读(间隙被其他事务插入记录) 

  RC不会升级

读锁 共享锁 悲观锁 / 写锁 排他锁

意向锁:针对表锁,mysql自己加,表的一个标识 代表已经有锁了

    意向共享锁:加共享锁前 先获取

   意向排他锁:

间隙锁:RR 两个值之间的空隙,可重复读隔离级别下才会生效

临键锁:

锁等待:

show status  like 'innodb_row_lock%';

  innodb_row_lock_current_waits  锁等待的数量

  innodb_row_lock_time_avg 每次等待平均时间

 innodb_row_lock_time_max 等待最长的一次时间

 innodb_row_lock_time 锁定的总时间

 innodb_row_lock_waits 总共等待的次数

select * from information_schema.innodb_trx;#查看事务

select * from information_schema.innodb_locks;#查看锁 8后更换data_locks

select * from information_schema.innodb_lock_waits;#锁等待  8更换data_lock_waits

show engine  innodb  status;#锁等待详细信息

 所有数据检索通过索引来完成,避免索引升级

 合理设计索引,缩小锁范围

  减少检索条件范围,避免间隙锁

  控制事务大小,减少锁定资源量和时间长度

  尽可能低的事务隔离级别

MVCC

RR事务开启,执行查询sql生成当前事务一致性视图read-view,该视图在事务结束前不会变化

   读已提交隔离级别每次执行查询sql都会重新生成

   视图由查询时未提交事务id数组min_id 和 已创建最大事务id max_id

   事务中查询从对应版本链最新数据逐条跟read-view做对比 read-view(100,300)300

事务

原子  一致  隔离  持久

大事务

    并发时连接池撑爆/锁太多超时阻塞/

    执行时间长 主从延迟 /回滚时间长/undo log膨胀/易死锁

优化:

 查询放事务外 (rr除外) / 避免远程调用 设置超时 / 避免一次性处理太多数据  / 

 更新设计加锁操作尽可能放到事务靠后的位置/能异步尽量异步 /  应用保证数据一致性 

隔离级别:undo多版本链

select 快照读 历史数据

update  insert   delete 当前读,最新数据

读未提交:read uncommit

  脏读,

读已提交:read commit 

    乐观锁 行锁  语句级快照读

    tx_id:

    roll_pointer:undo log

可重复读:repeatable read

    不能用版本号标识 读的是之前的   事务级快照

    幻读:新增的数据

  查询需要加锁吗?rr  读同一时间维度  需要

串行:serializable 

  读了之后不能修改

这篇关于mysql刨根问底的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/851908

相关文章

详解MySQL中DISTINCT去重的核心注意事项

《详解MySQL中DISTINCT去重的核心注意事项》为了实现查询不重复的数据,MySQL提供了DISTINCT关键字,它的主要作用就是对数据表中一个或多个字段重复的数据进行过滤,只返回其中的一条数据... 目录DISTINCT 六大注意事项1. 作用范围:所有 SELECT 字段2. NULL 值的特殊处

MySQL 用户创建与授权最佳实践

《MySQL用户创建与授权最佳实践》在MySQL中,用户管理和权限控制是数据库安全的重要组成部分,下面详细介绍如何在MySQL中创建用户并授予适当的权限,感兴趣的朋友跟随小编一起看看吧... 目录mysql 用户创建与授权详解一、MySQL用户管理基础1. 用户账户组成2. 查看现有用户二、创建用户1. 基

MySQL 打开binlog日志的方法及注意事项

《MySQL打开binlog日志的方法及注意事项》本文给大家介绍MySQL打开binlog日志的方法及注意事项,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要... 目录一、默认状态二、如何检查 binlog 状态三、如何开启 binlog3.1 临时开启(重启后失效)

SQL BETWEEN 语句的基本用法详解

《SQLBETWEEN语句的基本用法详解》SQLBETWEEN语句是一个用于在SQL查询中指定查询条件的重要工具,它允许用户指定一个范围,用于筛选符合特定条件的记录,本文将详细介绍BETWEEN语... 目录概述BETWEEN 语句的基本用法BETWEEN 语句的示例示例 1:查询年龄在 20 到 30 岁

MySQL DQL从入门到精通

《MySQLDQL从入门到精通》通过DQL,我们可以从数据库中检索出所需的数据,进行各种复杂的数据分析和处理,本文将深入探讨MySQLDQL的各个方面,帮助你全面掌握这一重要技能,感兴趣的朋友跟随小... 目录一、DQL 基础:SELECT 语句入门二、数据过滤:WHERE 子句的使用三、结果排序:ORDE

MySQL MCP 服务器安装配置最佳实践

《MySQLMCP服务器安装配置最佳实践》本文介绍MySQLMCP服务器的安装配置方法,本文结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下... 目录mysql MCP 服务器安装配置指南简介功能特点安装方法数据库配置使用MCP Inspector进行调试开发指

mysql中insert into的基本用法和一些示例

《mysql中insertinto的基本用法和一些示例》INSERTINTO用于向MySQL表插入新行,支持单行/多行及部分列插入,下面给大家介绍mysql中insertinto的基本用法和一些示例... 目录基本语法插入单行数据插入多行数据插入部分列的数据插入默认值注意事项在mysql中,INSERT I

一文详解MySQL如何设置自动备份任务

《一文详解MySQL如何设置自动备份任务》设置自动备份任务可以确保你的数据库定期备份,防止数据丢失,下面我们就来详细介绍一下如何使用Bash脚本和Cron任务在Linux系统上设置MySQL数据库的自... 目录1. 编写备份脚本1.1 创建并编辑备份脚本1.2 给予脚本执行权限2. 设置 Cron 任务2

SQL Server修改数据库名及物理数据文件名操作步骤

《SQLServer修改数据库名及物理数据文件名操作步骤》在SQLServer中重命名数据库是一个常见的操作,但需要确保用户具有足够的权限来执行此操作,:本文主要介绍SQLServer修改数据... 目录一、背景介绍二、操作步骤2.1 设置为单用户模式(断开连接)2.2 修改数据库名称2.3 查找逻辑文件名

SQL Server数据库死锁处理超详细攻略

《SQLServer数据库死锁处理超详细攻略》SQLServer作为主流数据库管理系统,在高并发场景下可能面临死锁问题,影响系统性能和稳定性,这篇文章主要给大家介绍了关于SQLServer数据库死... 目录一、引言二、查询 Sqlserver 中造成死锁的 SPID三、用内置函数查询执行信息1. sp_w