当前位置: 首页 > article >正文

其它查询优化策略

12、其它查询优化策略

12.1.EXISTS 和 IN 的区分
问题:不太理解哪种情况下应该使用 EXISTS,哪种情况应该用 IN。选择的标准是看能否使用表的索引吗?
回答:索引是个前提,其实选择与否还是要看表的大小。你可以将选择的标准理解为小表驱动大表。在这种方式下效率是最高的。

比如下面这样:

SELECT * FROM A WHERE cc IN (SELECT ce FROM B)
SELECT * FROM A WHERE EXISTS (SELECT cc FROM B WHERE B.cc=A.cc)

① 当 A 小于 B 时,用 EXISTS。因为 EXISTS 的实现,相当于外表循环,实现的逻辑类似于:

for i in A
	for j in B
		if j.cc == i.cc then ...

② 当 B 小于 A 时用 IN,因为实现的逻辑类似于:

for i in B
for j in A
if j.cc == i.cc then …
1
2
3
哪个表小就用哪个表来驱动,A 表小就用 EXISTS,B 表小就用 IN。

12.2.COUNT() 与 COUNT(具体字段)效率
问:在 MySQL 中统计数据表的行数,可以使用三种方式:SELECT COUNT(
)、SELECT COUNT(1) 和 SELECT 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 小的二级索引进行扫描。当没有二级索引的时候,才会采用主键索引来进行统计。

12.3.关于 SELECT(*)

在表查询中,建议明确字段,不要使用 * 作为查询的字段列表,推荐使用SELECT <字段列表> 查询。原因:
① MySQL 在解析的过程中,会通过查询数据字典将"*"按序转换成所有列名,这会大大的耗费资源和时间。
② 无法使用覆盖索引。

12.4.LIMIT 1 对优化的影响
(1)针对的是会扫描全表的 SQL 语句,如果你可以确定结果集只有一条,那么加上LIMIT 1的时候,当找到一条结果的时候就不会继续扫描了,这样会加快查询速度。

(2)如果数据表已经对字段建立了唯一索引,那么可以通过索引进行查询,不会全表扫描的话,就不需要加上LIMIT 1了。

12.5.多使用 COMMIT

(1)只要有可能,在程序中尽量多使用 COMMIT,这样程序的性能得到提高,需求也会因为 COMMIT 所释放的资源而减少。
(2)COMMIT 所释放的资源:
① 回滚段上用于恢复数据的信息;
② 被程序语句获得的锁;
③ redo / undo log buffer 中的空间;
④ 管理上述 3 种资源中的内部花费;


http://www.kler.cn/a/303388.html

相关文章:

  • Bugku CTF_Web——点login咋没反应
  • 专题十八_动态规划_斐波那契数列模型_路径问题_算法专题详细总结
  • 基于微信小程序的乡村研学游平台设计与实现,LW+源码+讲解
  • Android Studio 将项目打包成apk文件
  • OpenGL ES 共享上下文实现多线程渲染
  • 车-路-站-网”信息耦合的汽车有序充电
  • 基于SSM的大学新生报到系统+LW参考示例
  • Vue3实现打印功能
  • 数据结构---非线性--树
  • prometheus 集成 grafana 保姆级别安装部署
  • 数据结构与算法 第12天(排序)
  • 字符分类函数和字符串函数
  • 【PostgreSQL数据库表膨胀的一些原因】
  • springboot 单独新建一个文件实时写数据,当文件大于100M时按照日期时间做文件名进行归档
  • 2024121读书笔记|《不急:我们慢慢慢慢来》——做人呢,最重要的是开心
  • 从底层原理上理解ClickHouse 中的 Distributed 引擎
  • tomcat项目报错org.apache.jasper.JasperException: java.lang.NullPointerException
  • Python中的“异常”之旅:探索异常处理的艺术
  • 大语言模型之ICL(上下文学习) - In-Context Learning Creates Task Vectors
  • 用于安全研究的 Elastic Container Project
  • Java 行为型设计模式一口气讲完!*^____^*
  • Spring Cloud 搭建 Gateway 网关与统一登录模块:路径重写、登录拦截、跨域配置
  • 使用Jenkins扩展钉钉消息通知
  • 根据NVeloDocx Word模板引擎生成Word(五)
  • 9.12 TFTP通信
  • 阿里巴巴拍立淘API:实时图像搜索与快速响应的技术探索