首页 > 数据库 >MySQL

MySQL

时间:2023-04-27 18:14:06浏览次数:47  
标签:扫描 查询 索引 MySQL 驱动 NULL id

1、回表查询与索引覆盖

聚簇索引:主键索引一般是聚簇索引。聚簇索引的非叶子结点记录的是索引,叶子结点记录了对应的数据行(所有的字段)。

非聚簇索引:叶子结点记录的是普通索引列与主键的对应关系(不记录别的字段)。

如果走了普通索引,但想要 select 走的索引之外的字段,那么在根据非聚簇查完之后,就要根据行号去聚集索引进行回表

索引覆盖:条件和想要查的字段建立联合索引

select id,name,sex from user where name='shenjian';

将单列索引(name)升级为联合索引(name, sex),即可避免回表。

https://blog.csdn.net/guorui_java/article/details/111302542

 

2、利用延迟关联(就是子查询?)或者子查询优化超多分页场景

在具有大量数据的场景下,使用传统的 LIMIT offset, N 分页查询可能会导致性能问题。原因是MySQL不会跳过前 offset 行,而是获取 offset + N 行数据,然后丢弃前 offset 行,返回 N 行。

SELECT id,name FROM user_info WHERE dep_id = 1 LIMIT 100000,20

因为子查询没有获取 a.Name ,所以可以比一次查询【取然后丢弃前 offset 的 a.Name 数据】

SELECT a.id,a.NAME FROM user_info AS a,
    ( SELECT id FROM user_info WHERE dep_id = 1 LIMIT 
 100000,20 ) AS b 
WHERE a.id = b.id;

 

3、MySQL 索引访问方式

1、const: 通过主键或者【唯一】二级索引列常数的等值比较来定位一条记录的访问方法

2、ref : 搜索条件为二级索引列常数进行等值比较,形成的扫描区间为单点扫描区间,采用二级索引来执行查询的访问方法。由于二级索引不会限制索引列的唯一性,所以通过二级索引查询的记录可能有多条,此时使用二级索引执行查询的代价就取决于扫描区间中的记录条数。

3、ref_or_null:搜索条件为二级索引列常数进行等值比较,并且条件里还有 is null

4、range:使用索引执行查询时,对应的扫描区间为若干个单点扫描区间或者范围扫描区间的访问方法称为range(仅包含一个单点扫描区间的访问方法不能称为range访问方法,扫描区间为(负无穷,正无穷)的访问方法也不能称为range)

5、index:扫描【全部】二级索引记录的访问方法

6、all: 全表扫描

至少要达到 range 级别,要求是ref级别,如果可以是 const最好。

 

4、COUNT()

  COUNT(*)、COUNT(1) 都表示返回满足条件的结果集的总行数,与是否为NULL无关

  COUNT(字段),则表示返回满足条件的数据行里面,参数“字段”不为NULL的总个数

  COUNT(DISTINCT col) 计算该列除 NULL之外的不重复行数。

  COUNT(DISTINCT col1, col2) 如果其中一列全为NULL,那么即使另一列有不同的值,也返回为 0

当某一列的值全是NULL时,COUNT(col)的返回结果为 0,但SUM(col)的返回结果为NULL,因此使用 SUM()时需注意NPE(空指针)问题。可用 IFNULL(SUM(field), 0)

 

5、强制使用 IS NULL() 判断 null 值

NULL与任何值的直接比较都为 NULL。

1) NULL<>NULL的返回结果是 NULL,而不是 false。

2) NULL=NULL的返回结果是 NULL,而不是 true。

3) NULL<>1的返回结果是 NULL,而不是 true。

 

6、EXISTS 和 IN 小表驱动大表

  类似循环嵌套循环,外层循环是驱动,内层循环是被驱动

for(int i=5;.......)
{
   for(int j=1000;......)
   {}
}

  如果小的循环在外层,对于数据库连接来说就只连接5次,进行5000次操作,如果1000在外,则需要进行1000次数据库连接,从而浪费资源,增加消耗。这就是为什么要小表驱动大表。

 

  • 1 LEFT JOIN 左连接,左边为驱动表,右边为被驱动表.

 

  • 2 RIGHT JOIN 右连接,右边为驱动表,左边为被驱动表.
  • 3 INNER JOIN 内连接, mysql会选择数据量比较小的表作为驱动表,大表作为被驱动表.
  • 4 IN 子查询是驱动表,外层查询是被驱动表
  • 5 EXISTS 外层查询是驱动表,内层查询是被驱动表

 

可通过EXPLANIN查看SQL语句的执行计划,EXPLANIN分析的第一行的表即是驱动表

 

select count(1) from orders o where o.user_id in(select u.id from users u);
select count(1) from orders o where exists (select 1 from users u where u.id = o.user_id);

1.in:先查询in后面的users表,然后再去orders中过滤,也就是先执行子查询,结果出来后,再遍历主查询,遍历主查询是根据user_id和id相等查询的。

2.exists:主查询是内层循环,先查询出orders,查询orders就是外层循环,然后会判断是不是存在order_id和 users表中的id相等,相等才保留数据,查询users表就是内层循环。

 

7、IN 中数据过多,导致索引失效

当 in 中是常量时,IN肯定会走索引,但是当IN的取值范围较大时会导致索引失效,走全表扫描。

  mysql有个阈值,决定了阈值之下使用索引查询,而超过阈值则退化,优化器选择索引下潜。

 

8、条件中对于同一个字段使用到OR的SQL语句必须改写成用IN()

  MySQL 中OR的效率比IN低很多

WHERE
    id = 1 
    OR id = 2 
    OR id = 3;


WHERE
    id IN ( 1, 2, 3 );

 

8、UNION 和 UNION ALL

UNION 在进行表链接后会筛选掉重复的记录,所以在表链接后会对所产生的结果集进行排序运算,删除重复的记录再返回结果,如果表数据量大的话可能会导致用磁盘进行排序。

UNION ALL操作只是简单的将两个结果合并后就返回,所以可能存在重复记录。 需要结合业务需求分析使用UNION ALL的可行性。

9、SELECT ... FOR UPDATE

 

4、MySQL 索引失效的场景

  1、字段类型不同会造成隐式转换,导致索引失效。

标签:扫描,查询,索引,MySQL,驱动,NULL,id
From: https://www.cnblogs.com/suBlog/p/17359866.html

相关文章

  • MySQL----日期相关
    获取当前日期selectcurdate();结果: 2023-04-27获取当前日期为几号selectday(curdate())结果:27在当前日期上加上时间间隔selectDATE_ADD(curdate(),interval2day)结果:2023-04-29一、获取本月第一天selectDATE_ADD(curdate(),interval-day(curdate())+1day)--获取本......
  • spring boot jpa MYSQL教程mysql连接的空闲时间超过8小时后 MySQL自动断开该连接
     SunApr1608:15:36CST2023Therewasanunexpectederror(type=InternalServerError,status=500).PreparedStatementCallback;SQL[selectuserIdfromfamilyxiao_UserConnectionwhereproviderId=?andproviderUserId=?];Nooperationsallowedaftercon......
  • Mysql查询父、子节点
    一、概述相信大家在实际的开发工程中,都会遇到需要依据当前节点,查询出其上级节点或下级节点的需求。下面就我在工作过程中的处理方式记录如下,如有片面之处,欢迎批评指正。二、示例表结构初始表数据如图:查看表结构和初始数据脚本DROPTABLEIFEXISTS`t_cfg_region`;CREATE......
  • MySQL - SQL语句增加字段/修改字段/修改类型/修改默认值
    1.添加字段,比如我在数据表中添加一个age字段,类型为int(11)ALTERTABLEplayerADDCOLUMNageint(11);2.修改字段名,将age字段改成player_ageALTERTABLEplayerRENAMECOLUMNagetoplayer_age3.修改字段的数据类型,将player_age的数据类型设置为float(3,1)ALT......
  • DataX-在Windows上实现postgresql同步数据到mysql
    场景DataX-阿里开源离线同步工具在Windows上实现Sqlserver到Mysql全量同步和增量同步:https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/130330353在上面实现sqlserver到mysql的数据同步之后,如果要实现postgresql到mysql数据同步流程一样。以PostGis中的OGC元数据......
  • Linux安装Mysql5.7
    前言:还是和以前一样,linux安装软件的目录都是data目录1.进入data目录,创建mysql目录并进入该目录cd/datamkdirmysqlcdmysql 2.删除默认配置,不推荐rm-rf rm/etc/my.cnfy 3.上传"mysql-5.7.23-linux-glibc2.12-x86_64.tar.gz"文件到当前目录(/data/mysql)"m......
  • mysql字段类型json更新
    updatetbl_testsettest_json=JSON_REPLACE(test_json,'$."jsonFieldName"',(CAST(test_json->'$."jsonFieldName"'ASSIGNEDINTEGER)-70*365-19)*86400-3600*8)wheret......
  • MySQL锁机制详解-表锁与行锁
    转、MySQL锁机制详解-表锁与行锁https://blog.csdn.net/huangjhai/article/details/119011417  转:什么是线程死锁?如何避免死锁? 相互强占彼此资源,导致彼此等待。线程挂起 阻塞......
  • MySQL用的在溜,不知道业务如何设计也白搭!!!
    MySQL业务设计作者:博学谷狂野架构师GitHub:GitHub地址(有我精心准备的130本电子书PDF)只分享干货、不吹水,让我们一起加油!......
  • MySQL用的在溜,不知道业务如何设计也白搭!!!
    MySQL业务设计作者:博学谷狂野架构师GitHub:GitHub地址(有我精心准备的130本电子书PDF)只分享干货、不吹水,让我们一起加油!......