数据库性能系列之子查询

前言

16150c9aa797df4d8cc4176dc9a5fd78.png

说起数据库,想必一些朋友会认为,数据库不就是天天CRUD吗?只要我掌握了这几招,根本不在话下。是的,其实我也很赞同这个观点,对于大多数应用程序来说,只掌握这些内容,是可以胜任日常的开发工作的。

然而我们的程序不可能始终停留在测试环境,随着生产环境数据量的增大,以及用户规模的增长,数据库就会出现一些性能方面的问题。所以接下来的一段时间内,我们会学习一些数据库性能优化方面的内容,希望可以带给大家一些启迪和成长。今天,我们就从最基本的子查询讲起。

概述

ee6e0a3d0834f72c84a35fea4eb16288.png

子查询的定义本身很简单,就是一种嵌套查询。最常见的例子就是我们有两张表students和classes,为了简化说明,此处没有遵守三大范式,表中的字段如下:

sutdents

id
stu_namestu_ageclass_id
1
张三
15
1002
2李四
15
1001
3王五
16
1002
4朱六14
1003

classes

class_id
class_name
1001
语文
1002
数学
1003英语

此时我们想查询哪些学生选择了数学课,就可以使用子查询去查找结果:

SELECT stu_name FROM sutdents WHERE sutdents.class_id IN (SELECT class_id FROM classes WHERE class_name = '数学')

可以看出,我们在这里使用了IN操作符来关联子查询的结果,熟悉的伙伴一定清楚,还有一种子查询的方式叫做EXISTS,使用方式如下:

SELECT stu_name FROM sutdents s  WHERE EXISTS (SELECT 1 FROM classes c WHERE s.class_id = c.class_id AND class_name = '数学')

两种方式的查询结果都是一致的,我们找出了哪些学生选择了数学课:

5458908591455ea49c9fe5ca88a5f393.png

但实际上,这两种子查询的效率在不同的情况下是不一样的,下面我们来单独谈谈这两种方式的区别。

什么是IN

6fb888eb70bebb5b56fe70ad5b4e37d5.png

从字面意思来看,IN即为外部表的字段,使用内部嵌套查询的结果中作为条件去查询所需的结果。因此,使用IN时,内部嵌套的子查询只会查询一次,这里引申出一个概念,叫做:非关联子查询。

在我们上述的示例中,子查询会先从classes表中找出课程名称为“数学”的id,此时子查询只执行了一次。通过查询的结果,即数学课的id号,作为外部查询的条件,去查找最终的结果。

什么是EXISTS

cbd533c5f767d8b1384a2563768849e3.png

同样的,顾名思义,EXISTS即为“存在”。也就是说,在嵌套查询时,外部表的信息,需要在内部表的结果中存在,才可以查询出结果。因此,使用EXISTS时,内部嵌套的子查询会查询多次,次数取决于外部表的记录条目,最终返回对应的结果给外部表,这个概念叫做:关联子查询。

在上述示例中,查询语句会先从students表中找出每一条记录对应的class_id,然后传递给内部的子查询,内部子查询使用该class_id进行匹配,去classes表中查找满足class_id和class_name为“数学”的记录,再返回给外部的表。在此过程中,只有完全匹配的记录,才会呈现最终的结果。

如何优化子查询

beca99fcde67ebbb776b173e0ca62617.png

在以往的很多经验和一些文章中经常会提到,优化SQL语句,需要使用EXISTS来代替IN,即可达到效果。那么这句话究竟是不是正确的呢?

通过今天的学习,我们现在已经知道,这句话不完全正确,也不完全错误。究其根因,我们已经了解了IN和EXISTS的特性,所以结论如下:

1、如果一个语句中,子查询外部的表A,数量小于子查询内部的表B,那么此时,使用EXISTS的效率,是要大于IN的。这是因为EXISTS每次查询会循环表A中的数据,然后传入表B进行匹配,此种情况下,使用EXISTS循环次数少,需要查询的记录条目也更少。

2、反之,如果子查询外部的表A,数量大于子查询内部的表B,那么此时,使用IN的效率会更高。此时使用IN可以缩小要查找的记录范围,最终匹配表A时可以减少记录的大小。

总结

be06a1ac41ee1d320bd3110c58f5fb9b.png

今天我们阐述了子查询的概念和一些简单的用法,以及一些优化方式。我们可以将子查询分为关联子查询和非关联子查询两种模式,分别对应IN和EXISTS的用法。最后我们在优化子查询时提到了使用哪种方式取决于外表和内表的大小关系,其实优化的重心在于使用小表来驱动大表的原则,这些你都学会了吗?

下一期我们会从数据库索引的角度来继续讲述数据库性能优化的方式,朋友们,我们下期再见!

9dc334ca83a6ef38fb4cd79140608110.png

您的点赞和在看是我创作的最大动力,感谢支持

ea7d615b81970e0db97f9beb5cd0d8e8.jpeg

cc4a1e4bc96ad0f9e025d9163a6dbac5.png

e0d15d7d4ddbe53a51fbadf656f87ab6.png

公众号:wacky的碎碎念

知乎:wacky

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/284379.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

laravel 内部验证码

为什么80%的码农都做不了架构师?>>> 1.找到此文件composer.json 如下图添加 "gregwar/captcha": "1.*" 行代码 2.在命令行中执行 composer update 安装完成后 3.找到控制器添加如下代码 public function captcha($tmp) {//生成验证…

k8s docker集群搭建

一、Kubernetes系列之介绍篇 1.背景介绍 云计算飞速发展 - IaaS - PaaS - SaaS Docker技术突飞猛进 - 一次构建,到处运行 - 容器的快速轻量 - 完整的生态环境 2.什么是kubernetes 首先,他是一个全新的基于容器技术的分布式架构领先方案。Kubernetes(k8…

如何让最小 API 绑定查询字符串中的数组

前言在上次的文章中,我们实现了《让 ASP.NET Core 支持绑定查询字符串中的数组》:[HttpGet] public string Get([FromQuery][ModelBinder(BinderType typeof(IntArrayModelBinder))] int[] values) {return string.Join(" ", values.Select(p…

Kubernetes api-server源码阅读2(Debug Kubernetes篇)

云原生学习路线导航页(持续更新中) 本文是 Kubernetes api-server源码阅读 系列第二篇,主要讲述如何实现 kubernetes api-server 的 debug 参考b站视频地址:Kubernetes源码开发之旅二 1.本篇章任务 Go-Delve:go语言的…

webrtc 视频 demo

webrtc 视频 demo webrtc网上封装的很多&#xff0c;demo很多都是一个页面里实现的&#xff0c;今天实现了个完整的 &#xff0c; A 发视频给 BA webrtc.html作为offer <!DOCTYPE html> <html id"home" lang"en"><head><meta http-e…

[转]阿里开源低代码引擎LowCodeEngine

一、什么是低代码引擎 低代码引擎是具备强大扩展能力的低代码研发框架&#xff0c;使用者只需要基于低代码引擎便可以快速定制符合自己业务需求的低代码平台。同时&#xff0c;低代码引擎还在标准低代码设计器的基础上提供了简单易用的定制扩展能力&#xff0c;能够满足业务独特…

Beyond Istio OSS——Istio服务网格的现状与未来

作者&#xff1a;宋净超&#xff08;Jimmy Song&#xff09;&#xff0c;原文地址&#xff1a;https://jimmysong.io/blog/beyond-istio-oss/本文根据笔者在 GIAC 深圳 2022 年大会上的的演讲《Beyond Istio OSS —— Istio 的现状及未来》[1] 整理而成&#xff0c;演讲幻灯片见…

js多维数组扁平化

数组扁平化&#xff0c;就是将多维数组碾平为一维数组&#xff0c;方便使用。 一&#xff1a;例如&#xff0c;一个二维数组 var arr [a, [b, 2], [c, 3, x]]&#xff0c;将其扁平化&#xff1a; 1. 通过 apply 借用数组的 concat 方法&#xff1a; [].concat.apply([], arr)…

第16讲 用户程序的结构与执行

转载于:https://www.cnblogs.com/atuo/p/5609843.html

两种方法清除Excel保护密码

一、利用VBA脚本直接清除 打Excel&#xff0c;打开脚本编辑器&#xff08;AltF11&#xff09;或者如图&#xff0c;右键sheet名称 输入代码并运行&#xff0c;即可清除密码保护&#xff1a; Sub DeletePW()ActiveSheet.Protect DrawingObjects:True, Contents:True, AllowFil…

jsonp-反向代理-CORS解决JS跨域问题的个人总结

jsonp-反向代理-CORS解决JS跨域问题的个人总结 网上说了很多很多&#xff0c;但是看完之后还是很混乱&#xff0c;所以我自己重新总结一下。解决 js 跨域问题一共有8种方法&#xff0c; jsonp&#xff08;只支持 get&#xff09;反向代理CORSdocument.domain iframe 跨域windo…

EasyNetQ-用于使用 RabbitMQ 的 .NET API开源的工具库

Part1介绍EasyNetQ 的目标是提供一个库&#xff0c;用于在 .NET 中使用 RabbitMQ 尽可能简单。为了做到这一点&#xff0c;它通过强制执行一些简单的约定来以灵活性换取简单性。这些包括&#xff1a;消息应该由 .NET 类型表示。消息应按其 .NET 类型进行路由。这意味着消息是由…

C# 实例解释面向对象编程中的依赖反转原则

在面向对象编程中&#xff0c;SOLID 是五个设计原则的首字母缩写&#xff0c;旨在使软件设计更易于理解、灵活和可维护。这些原则是由美国软件工程师和讲师罗伯特C马丁(Robert Cecil Martin)提出的许多原则的子集&#xff0c;在他2000年的论文《设计原则与设计模式》中首次提出…

Linux学习笔记之一————什么是Linux及其应用领域

1.1认识Linux 1&#xff09;什么是操作系统 2&#xff09;现实生活中的操作系统 win7 Mac Android iOS 3&#xff09; 操作系统的发展史 &#xff08;1&#xff09;Unix 1965年之前的时候&#xff0c;电脑并不像现在一样普遍&#xff0c;它可不是一般人能碰的起的&#xff0c;…

Lucene详解

一.lucene原理 Lucene 是apache软件基金会一个开放源代码的全文检索引擎工具包&#xff0c;是一个全文检索引擎的架构&#xff0c;提供了完整的查询引擎和索引引擎&#xff0c;部分文本分析引擎。它不是一个完整的搜索应用程序&#xff0c;而是为你的应用程序提供索引和搜索功能…

.NET 6.0中使用Identity框架实现JWT身份认证与授权

原文作者&#xff1a;Sarathlal Saseendran原文链接&#xff1a;https://www.c-sharpcorner.com/article/jwt-authentication-and-authorization-in-net-6-0-with-identity-framework/翻译&#xff1a;沙漠尽头的狼&#xff08;谷歌翻译加持&#xff09;介绍微软于 2021 年 11 …

adb devices 里面有很多 emulator-XXXX的解决方法

2019独角兽企业重金招聘Python工程师标准>>> adb kill-server 转载于:https://my.oschina.net/sfshine/blog/700354

MQ(Message Queue)简介

一、何为MQ&#xff1f; MQ全称为Message Queue, 消息队列&#xff08;MQ&#xff09;是一种应用程序对应用程序的通信方法。应用程序通过读写出入队列的消息&#xff08;针对应用程序的数据&#xff09;来通信&#xff0c;而无需专用连接来链接它们。消息传递指的是程序之间通…

Blazor University (39)JavaScript 互操作 —— 更新 document title

原文链接&#xff1a;https://blazor-university.com/javascript-interop/calling-javascript-from-dotnet/updating-the-document-title/更新 document title源代码[1]在创建 Blazor 布局[2]部分中&#xff0c;我们看到了 Blazor 应用程序如何存在于 HTML&#xff08;或 cshtm…

IIS 日志文件位置

IIS 6 Log files location IIS 6中日志文件的位置%windir%\System32\LogFilesIIS 7 Log files location IIS的日志文件的位置%SystemDrive%\inetpub\logs\LogFiles用户每打开一次网页&#xff0c;iis 都会记录用户IP、访问的网页地址、访问时间、访问状态等信息&#xff0c;这些…