首页 > 数据库 >MySQL 索引之外的相关查询优化总结

MySQL 索引之外的相关查询优化总结

时间:2024-06-30 22:59:15浏览次数:3  
标签:COUNT ICP MySQL 查询 索引 使用 排序

在这之前先说明几个概念:
1、驱动表和被驱动表:驱动表是主表,被驱动表是从表、非驱动表。驱动表和被驱动表并非根据 from 后面表名的先后顺序而确定,而是根据 explain 语句查询得到的顺序确定;展示在前面的是驱动表,后面的是非驱动表。
2、关联查询的类型非为:内连接(inner join)、左外连接(left join)、右外连接(right join)、全外连接(full join);
一、关联查询优化
1、整体效率比较:INLJ>BNLJ>SNLJ(这些值在EXPLAIN语句中Extra字段展示)
2、永远用小结果集驱动大结果集(其本质就是减少外层循环的数据数量)(小的度量单位指的是 表行数"每行大小

#推荐
select t1.b,t2.* from t1 Istraight_join t2 on(t1.b=t2.b)where t2.id<=188;
#不推荐
select t1.b,t2.* from t2 straight_join t1 on (t1.b=t2.b) where t2.id<=108; 

3、为被驱动表匹配的条件增加索引(减少内层表的循环匹配次数)
4、增大join buffer size的大小(一次缓存的数据越多,那么内层包的扫表次数就越少).
5、减少驱动表不必要的字段査询(字段越少,join buffer 所缓存的数据就越多);
实践得到以下结论:
结论1:对于内连接来说,查询优化器可以决定谁来作为驱动表,谁作为被驱动表出现
结论2:对于内连接来讲,如果表的连接条件中只能有一个字段有索引,则有索引的字段所在的表会被作为被驱动表
结论3:对于内连接来说,在两个表的连接条件都存在索引的情况下,会选择小表作为驱动表。小表驱动大表
关联查询优化细节可参考视频教程上部下部
二、子查询优化和排序优化(相关视频教程)
1、子查询是 MySQL 的一项重要的功能,可以一次性完成很多逻辑上需要多个步骤才能完成的SQL操作 ,能够帮助我们通过一个 SQL 语句实现比较复杂的查询。但是子查询的执行效率不高。原因如下:
(1) 执行子查询时,MySQL需要为内层查询语句的查询结果建立一个临时表,然后外层查询语句从临时表中查询记录。查询完毕后,再撤销这些临时表。这样会消耗过多的 CPU 和 IO 资源,产生大量的慢查询。
(2) 子查询的结果集存储的临时表,不论是内存临时表还是磁盘临时表都不会存在索引,所以查询性能会受到一定的影响。
(3) 对于返回结果集比较大的子查询,其对查询性能的影响也就越大。
在MySQL中,可以使用连接(JOIN)查询来替代子查询。连接查询不需要建立临时表,其速度比子查询要快,如果查询中使用索引的话,性能就会更好。
2、在查询时不仅要在 WHERE 条件字段上加索引,还要在在 ORDER BY 字段上添加索引,因为在 MySQL 中,支持两种排序方式,分别是 FileSort 和 Index 排序。
◆ Index 排序中,索引可以保证数据的有序性,不需要再进行排序,效率更高。
◆ Filesort 排序则一般在内存中进行排序,占用 CPU 较多。如果待排结果较大,会产生临时文件 IO 到磁盘进行排序的情况,效率较低。
优化建议如下(这块的内容很详细,具体实践一定要看教程):
(1) SQL 中,可以在 WHERE 子句和 ORDER BY 子句中使用索引,目的是在 WHERE 子句中 避免全表扫描,在 ORDER BY 子句避免使用 FileSort 排序。当然,某些情况下全表扫描,或者 FileSort 排序不一定比索引慢。但总的来说,我们还是要避免,以提高查询效率。
(2) 尽量使用 Index 完成 ORDER BY 排序。如果 WHERE 和 ORDER BY 后面是相同的列就使用单索引列;如果不同就使用联合索引。
(3) 无法使用 Index 时,需要对 FileSort 方式进行调优。
三、GROUP BY优化和分页查询优化(相关视频教程)
1、group by 的优化策略主要包含以下六点
(1) group by 使用索引的原则几乎跟order by一致 ,group by 即使没有过滤条件用到索引,也可以直接使用索引。
(2) group by 先排序再分组,遵照索引建的最佳左前缀法则
(3) 当无法使用索引列,可以增大max_length_for_sort_data和sort_buffer_size参数的设置
(4) where效率高于having,能写在where限定的条件就不要写在having中了
(5) 减少使用 order by,和业务沟通能不排序就不排序,或将排序放到程序端去做。Order by、group by、distinct 这些语句较为耗费 CPU,数据库的CPU资源是极其宝贵的。
(6) 包含了order by、group by、distinct 这些查询的语句,where 条件过滤出来的结果集请保持在1000行以内,否则SQL会很慢。
2、一般分页查询时,通过创建覆盖索引能够比较好地提高性能。一个常见又非常头疼的问题就是 limit 2000000,10此时需要MySQL排序前2000010 记录,仅仅返回2000000-2000010 的记录,其他记录丢弃,查询排序的代价非常大。

EXPLAIN SELECT *FROM student LIMIT 2000000,10;

优化思路一
在索引上完成排序分页操作,最后根据主键关联回原表查询所需要的其他列内容。

EXPLAIN SELECT * FROM student t,(SELECT id FROM student ORDER BY id LIMIT 2000000,10) a WHERE t.id = a.id;

优化思路二
该方案适用于主键自增的表,可以把 Limit 查询转换成某个位置的查询。

EXPLAIN SELECT * FROM student WHERE id > 2000000 LIMIT 10;

四、覆盖索引的使用(相关视频教程)
1、什么是覆盖索引?
理解方式一:索引是高效找到行的一个方法,但是一般数据库也能使用索引找到一个列的数据,因此它不必读取整个行。毕竟索引叶子节点存储了它们索引的数据;当能通过读取索引就可以得到想要的数据,那就不需要读取行了。一个索引包含了满足查询结果的数据就叫做覆盖索引。
理解方式二:非聚簇复合索引的一种形式,它包括在查询里的SELECT、JOIN和WHERE子句用到的所有列(即建索引的字段正好是覆盖查询条件中所涉及的字段)。
简单说就是,索引列+主键包含SELECT 到 FROM之间查询的列。
2、索引覆盖的好处
(1) 避免Innodb表进行索引的二次查询(回表)
Innodb是以聚集索引的顺序来存储的,对于Innodb来说,二级索引在叶子节点中所保存的是行的主键信息,如果是用二级索引查询数据,在查找到相应的键值后,还需通过主键进行二次查询才能获取我们真实所需要的数据。在覆盖索引中,二级索引的键值中可以获取所要的数据,避免了对主键的二次査询 ,减少了IO操作,提升了查询效率。
(2) 可以把随机 IO 变成顺序 IO 加快查询效率
由于覆盖索引是按键值的顺序存储的,对于 IO 密集型的范围査找来说,对比随机从磁盘读取每一行的数据 IO 要少的多,因此利用覆盖索引在访问时也可以把磁盘的随机读取的 IO 转变成索引查找的顺序IO 。
由于覆盖索引可以减少树的搜索次数,显著提升查询性能,所以使用覆盖索引是一个常用的性能优化手段。
3、索引覆盖的缺点
索引字段的维护总是有代价的。因此,在建立冗余索引来支持覆盖索引时就需要权衡考虑了。这是业务 DBA,或者称为业务数据架构师的工作。
五、索引条件下推(ICP)(相关视频教程)

select * from a where key > 'z' and key like '%a' 

以上查询语句在使用和不适用 ICP 两种场景如下
1、在不使用 ICP 索引扫描的过程:
storage层:只将满足index key条件的索引(key>‘z’)记录对应的整行记录取出,返回给server层,回表
server 层:对返回的数据,使用后面的where条件(key like ‘%a’)过滤,直至返回最后一行。
2、使用 ICP 扫描的过程:
storage层:首先将index key条件满足的索引(key>‘z’)记录区间确定,然后在索引上使用index filter进行(key like ‘%a’)过滤。将满足的index filter条件的索引记录才去回表取出整行记录返回server层。不满足index filter条件的索引记录丢弃,不回表、也不会返回server层。
server 层:对返回的数据,使用table filter条件做最后的过滤。
3、ICP 的开启/关闭
·默认情况下启用索引条件下推。可以通过设置系统变量 optimizer_switch 控制:index_condition_pushdown

#打开索引下推
SET optimizer switch='index condition pushdown=off':
#关闭索引下推
SET optimizer_switch='index_condition_pushdown=on';

4、ICP的使用条件
(1) 如果表访问的类型为 range、ref、eq_ref和ref_or_null 可以使用ICP
(2) ICP可以用于 InnoDB 和MyISAM 表,包括分区表 InnoDB和 MyISAM 表
(3) 对于 InnoDB 表,ICP 仅用于`二级索引’。ICP 的目标是减少全行读取次数,从而减少 /0 操作。
(4) 当SQL使用覆盖索引时,不支持ICP。为这种情况下使用ICP 不会减少 IO。
(5) 相关子查询的条件不能使用ICP
六、其他查询优化策略(相关视频教程)
1、EXISTS 和 IN 的区分
索引是个前提,其实选择与否还会要看表的大小。你可以将选择的标准理解为小表驱动大表。在这种方式下效率是最高的。
2、COUNT(*)、COUNT(1)与COUNT(具体字段)效率
前提:如果你要统计的是某个字段的非空数据行数,则另当别论,毕竟比较执行效率的前提是结果一样才可以。

环节1:COUNT(星)和COUNT(1)都是对所有结果进行COUNT,COUNT(星)和COUNT(1)本质上并没有区别(二者执行时间可能略有差别,不过你还是可以把它俩的执行效率看成是相等的)。如果有WHERE子句,则是对所有符合筛选条件的数据行进行统计;如果没有WHERE子句,则是对数据表的数据行数进行统计。

环节2:如果是MyISAM存储引擎,统计数据表的行数只需要O(1)的复杂度,这是因为每张MyISAM的数据表都有一个meta信息存储了row_count值,而一致性则是由表级锁来保证的。
如果是InnoDB存储引擎,因为InnoDB支持事务,采用行级锁和MVCC机制,所以无法像MyISAM一样,维护一个row_count变量,因此需要采用扫描全表,是O(n)的复杂度,进行循环+计数的方式来完成统计。

环节3:在InnoDB引擎中,如果采用COUNT(具体字段)来统计数据行数,要尽量采用二级索引。因为主键采用的索引是聚簇索引,聚簇索引包含的信息多,明显会大于二级索引(非聚簇索引)。对于COUNT(*)和COUNT(1)来说,它们不需要查找具体的行,只是统计行数,系统会自动采用占用空间更小的二级索引来进行统计。
如果有多个二级索引,会使用key_len小的二级索引进行扫描。当没有二级索引的时候,才会采用主键索引来进行统计。

3、关于SELECT(星)
在表查询中,建议明确字段,不要使用 * 作为查询的字段列表,推荐使用SELECT <字段列表> 查询。原因:
(1) MySQL 在解析的过程中,会通过查询数据字典将"*"按序转换成所有列名,这会大大的耗费资源和时间。
(2) 无法使用覆盖索引
4、LIMIT 1 对优化的影响
针对的是会扫描全表的 SQL 语句,如果你可以确定结果集只有一条,那么加上LIMIT 1的时候,当找到一条结果的时候就不会继续扫描了,这样会加快查询速度。
如果数据表已经对字段建立了唯一索引,那么可以通过索引进行查询,不会全表扫描的话,就不需要加上LIMIT 1了。
5、多使用 COMMIT
只要有可能,在程序中尽量多使用 COMMIT,这样程序的性能得到提高,需求也会因为 COMMIT 所释放的资源而减少。
COMMIT 所释放的资源:
(1) 回滚段上用于恢复数据的信息
(2) 被程序语句获得的锁
(3) redo / undo log buffer 中的空间
(4) 管理上述 3 种资源中的内部花费

标签:COUNT,ICP,MySQL,查询,索引,使用,排序
From: https://blog.csdn.net/qq_39964887/article/details/140071988

相关文章

  • “了解MySQL中的enum枚举数据类型“
    目录#开篇1.创建包含枚举类型的表2.插入枚举类型的数据3.查询包含枚举类型的表4.更新枚举类型的数据5.使用枚举类型的好处注意事项示例总结附加#开篇        在数据库中,枚举(ENUM)是一种数据类型,用于存储一组预定义的值。这在某些情况下非常有用,例如......
  • MySQL面试重点-2
    16.MySQL数据引擎:引擎分类:showengines命令查看数据库支持的存储引擎。描述一下InnoDB和MyISAM的区别?**InnoDB存储限制64TB,而MyISAM存储限制256TB;InnoDB支持事物,而MyISAM不支持;InnoDB支持外键,而MyISAM不支持;InnoDB支持行级锁(默认)+表级锁,而MyISAM支持表级锁;InnoDB支持MVCC......
  • mysql主从同步
    mysql主从同步1.1介绍#什么是mysql主从同步MySQL主从复制(Master-SlaveReplication)是一种数据复制技术,用于在多个数据库服务器之间的数据同步。在主从复制架构中,一个服务器被设置为主服务器(Master),充当数据源,其他服务器被设置为从服务器(Slave),用来复制主服务器的数据。#......
  • mysql默认存储引擎--innodb存储引擎(详解)
    官方解释:    InnoDB,是MySQL的数据库引擎之一,现为MySQL的默认存储引擎,为MySQLAB发布binary的标准之一。InnoDB由InnobaseOy公司所开发,2006年五月时由甲骨文公司并购。与传统的ISAM与MyISAM相比,InnoDB的最大特色就是支持了ACID兼容的事务(Transaction)功能,类似于Postgre......
  • Mysql--B+树--数据结构
    基本概念-B+树/B树B树(B-tree)和B+树(B+tree)是常见的自平衡搜索树数据结构,用于在存储和检索大量数据时提供高效的操作。它们具有一些共同的基本概念:节点(Node):B树和B+树的数据存储在节点中。节点可以包含多个关键字和对应的指针。在B树中,叶子节点和内部节点的结构相同,都存储数据......
  • 安装MySQL
    安装MySQLyum安装MySQL[root@7-1~]#yuminstallmariadb-server-y[root@7-1~]#systemctlstartmariadb.service[root@7-1~]#mysql[root@7-1~]#mysql_secure_installation#初始化设置先输入密码一路回车[root@7-1~]#tee/etc/yum.repos.d/mysql.repo<<EOF......
  • MySQL优化
    MySQL优化1、尽量避免使用子查询例:SELECT*FROMt1WHEREid(SELECTidFROMt2WHEREname='chackca');其子查询在Mysql5.5版本里,内部执行计划是这样:先查外表再匹配内表,而不是先查内表t2,当外表的数据很大时,查询速度会非常慢在MariaDB10/Mysql5.6版本里,采用join关联方式......
  • 深入解析MySQL语句的执行步骤
    目录MySQL架构概述语句执行步骤总览连接管理与线程处理语法解析查询缓存语义解析与预处理查询优化执行计划生成存储引擎层执行结果集返回优化查询性能的技巧结论MySQL架构概述在深入探讨MySQL语句执行的具体步骤之前,我们先来了解MySQL的整体架构。MySQL架构主要包括以下......
  • 基于JSP和MySQL的小说阅读网站系统
    开头语:你好,我是计算机专业的猫哥,如果你对小说阅读网站感兴趣,欢迎联系我。开发语言:JSP数据库:MySQL技术:JSP+Java工具:MySql数据库,Java开发工具系统展示首页管理员功能模块读者后台功能模块作者后台功能模块摘要随着网络的发展,小说阅读行业迅速壮大,小说阅读网......
  • Fastapi 项目第二天首次访问时数据库连接报错问题Can't connect to MySQL server
    问题描述Fastapi项目使用sqlalchemy连接的mysql数据库,每次第二天首次访问数据库相关操作,都会报错:sqlalchemy.exc.OperationalError:(pymysql.err.OperationalError)(2003,"Can'tconnecttoMySQLserveron'x.x.x.x'([Errno111]Connectionrefused)")问题分析从出......