在上面的执行示例中,我们已经了解到了什么是子查询。那么子查询可以按照查询返回的不同结果,进行一些简单的分类,如下:
对应的是限制条件(格式类似“field<op>consant”, field表示列对象,op是操作符如"="、">"等)。
前面说了mysql会吧一些冗余的sql语句查询优化重写,比如多于的括号,比如有的外连接其实跟内连接类似,可以优化查询表的顺序。子查询又分为相关和不相关子查询,如果子查询过滤条件里有外层查询的参数,则是相关子查询,反之则是不相关子查询。Any函数就代表只要有一个就行,最小的,all代表必须所有的都满足这个条件,所以必须最大的也满足。当我们判断子查询里是否存在的时候,则用exists判断,有则返回true。
1.3 子查询 语法:select * from 表1 where (子查询) 外面的查询称为父查询 子查询为父查询提供查询条件 1.3.1 标量子查询 特点:子查询返回的值是一个 -- 查找笔试成绩是80的学生 mysql> select * from stuinfo where stuno=(select stuno from stumarks where writtenexam=80); +--------+---------+--------+--------+---------+-------
在 SQL 语言中,一个 SELECT-FROM-WHERE 语句称为一个查询块。当获得一个查询的答案需要多个步骤的操作,首先必须创建一个查询来确定用户不知道但包含在数据库中的值,将一个查询块嵌套在另一个查询块的 WHERE 字句或 HAVING 短语的条件中查询块称为子查询或内层查询。外部的 SELECT 查询语句,称为主查询或外查询。按结果集的行列数不同子查询可以分为 4 种 ♞ 标量子查询(结果集只有一行一列) ♞ 列子查询(结果集只有一列多行) ♞ 行子查询(结果集有一行多列) ♞ 表子查询(结果集一般为多行多列)
前面说了子查询里有no/any/all不能用limit,group by,order by等,他会被查询优化器优化掉,子查询可能会物化转成内连接semi-join查询,物化就是会吧子查询看做一个表,如果数据太大,超过系统变量tmp_table_size,则会在磁盘里创建b+树的临时表,如果比较小,则会创建内存里hash树的临时表,之后会物化表转连接,但如果直接转where 和on,则可能会出现子查询多条的情况,我们的真实需求并不需要多条,所以有了semi-join。
通过执行计划可以看出,先执行的是DEPENDENT SUBQUERY这部分(id大的优先执行),也就是select dname from dept d where e.deptno = d.deptno但是这部分是不能单独执行的,所以猜测mysql对这部分做了处理,处理成类似这种select d.dname,e.deptno from dept d join emp e on d.deptno = e,deptno,生成了一个临时表,然后再执行主表和临时表的连表查询(临时表的意思是啥?比如dept表有很多列,同时又很多行,其中还有一大部分不满足d.deptno = e,deptno这个条件,此时临时表相对于对大表做了一个精简)
在SQL语言中,一个SELECT-FROM-WHERE语句称为一个查询块。当获得一个查询的答案需要多个步骤的操作,首先必须创建一个查询来确定用户不知道但包含在数据库中的值,将一个查询块嵌套在另一个查询块的WHERE字句或HAVING短语的条件中查询块称为子查询或内层查询。上层的查询块曾为父查询或外层查询。子查询的结果作为输入传递回“父查询”或“外部查询”。父查询将这个值结合到计算中,以便确定最后的输出。
先看看具体有哪些字段: mysql> EXPLAIN SELECT 1; 其实除了以SELECT开头的查询语句,其余的DELETE、INSERT、REPLACE以及UPDATE语句前边都可以加上EXPLAIN这个词儿,用来查看这些语句的执行计划 建两张测试表: CREATE TABLE t1 ( id INT NOT NULL AUTO_INCREMENT, key1 VARCHAR(100), key2 VARCHAR(100), key3 VARCHAR(100),
前两天开发找DBA解决一个含有子查询的慢sql,我们通过将其修改为关联查询和添加索引解决。考虑到 大多数开发并没有准确的理解 MySQL 的子查询执行原理。本文介绍如何解决子查询慢查的思路。
(1)SELECT子句是必选的,其它子句如WHERE子句、GROUP BY子句等是可选的。
前面说了explain的table是表名,显示在前面的代表驱动表,正常select会出现不同的id,但如果子查询本来是两个select,但被优化成连接查询,就会导致是相同的id,union查询会出现临时表,id为null,这个临时表作用于去重,union all不需要去重,所以也就不需要建立临时表。
在数据库查询中,多表查询是一项非常常见且重要的任务。它允许我们从多个相关联的表中检索和组合数据,以满足各种复杂的查询需求。在多表查询中,子查询是一种强大的工具,用于在查询中嵌套另一个查询。本文将深入探讨MySQL中的子查询,包括什么是子查询、如何编写子查询以及使用子查询解决的常见查询问题。
在一个表表达中可以调用另一个表表达式,这个被调用的表表达式叫做子查询(subquery),我么也称作子选择(subselect)或内嵌选择(inner select)。子查询的结果传递给调用它的表表达式继续处理。
mysql 中 SELECT 命令类似于其他编程语言的 print 或 write,可用来显示字符串、数字、数学表达式的结果等
上节课我们给大家介绍了MySQL分组查询与聚合函数的使用方法,具体可回顾MySQL分组查询与聚合函数的使用方法(三)。本节课我们将介绍where条件查询中的IN关键字子查询的使用方法。
explain显示了mysql如何使用索引来处理select语句以及连接表。可以帮助选择更好的索引和写出更优化的查询语句。
select查询的序列号,包含一组数字,表示查询中执行select子句或者操作表的顺序 id号分为三种情况: 1、如果id相同,那么执行顺序从上到下 2、如果id不同,如果是子查询,id的序号会递增,id值越大优先级越高,越先被执行 3、id相同和不同的,同时存在:相同的可以认为是一组,从上往下顺序执行,在所有组中,id值越大,优先级越高,越先执行
浏览器中打开链接:http://www.itsoku.com/article/209
1、按位置分类:子查询在外部查询出现的位置,分为where字查询和from子查询。
说明2:as dept_name 是给dept.name 起的别名,防止查询结果中出现两个name字段,会有歧义
爱可生 DBA 团队成员,擅长故障分析、性能优化,个人博客:https://www.jianshu.com/u/a95ec11f67a8,欢迎讨论。
我们有一个 SQL,用于找到没有主键 / 唯一键的表,但是在 MySQL 5.7 上运行特别慢,怎么办?
我们在使用MySQL的时候,用的最多的情况可能就是select语句了,当我们在一个表查找数据的时候,经常会遇到查找的速度比较慢的情况,作为一名DBA,我也会经常遇见业务方写的SQL性能不太好的情况,这种情况下,通常会让业务方去进行调优。而判断一条SQL语句是否会变慢的最主要依据还是"执行计划"。
explain显示了MySQL如何使用索引来处理select语句以及连接表。可以帮助选择更好的索引和写出更优化的查询语句。下面是一个例子:
今天客户那边遇到一个问题:多选文件进行操作,数据量一大后台处理就特别慢,浏览器显示504超时。为了验证问题是否出在sql语句,所以用以下方法来分析:
本文示例 SQL 中的表,都来自于官方提供的测试数据库 sakila,下载链接如下:https://downloads.mysql.com/docs/sakila-db.tar.gz
id SELECT识别符。这是SELECT的查询序列号。 select_type 1.SIMPLE:简单的SELECT,不实用UNION或者子查询。 2.PRIMARY:最外层SELECT。 3. UNION:第二层,在SELECT之后使用了UNION。 4.DEPENDENT UNION:UNION语句中的第二个SELECT,依赖于外部子查询。 5.UNION RESULT:UNION的结果。 6.SUBQUERY:子查询中的第一个SELECT。 7.DEPENDENT SUBQ
MySQl从4.11版后已经完全支持嵌套查询了,那么下面举些简单的嵌套查询的例子吧(源程序来自MySQL User Manual):
使用 EXPLAIN 查看执行计划, 5.6后可以加参数 EXPLAIN FORMAT=JSON xxx输出json格式的信息。
基本概念: 可合并多个相似的选择查询结果的结果集,等同于将一个表追加到另一个表,从而实现将两个表的查询结果组合到一起,使用 Union 或 Union all。 注意: 这个合并是纵向合并,字段数不变,多个查询的结果合并。
当我们遇到一个慢查询语句时,首先要做的是检查所编写的 SQL 语句是否合理,优化 SQL 语句从而提升查询效率。所以对 SQL 有一个整体的认识是有必要的。
子查询也称为内查询(Inner Query),必须位于括号之中。包含子查询的查询称为外查询(Outer Query)。子查询支持多层嵌套,也就是子查询可以包含其他子查询。
子查询定义在一个完整的查询语句中包含的子查询块被称为子查询。通常情况下,我们可以将出现在SELECT、WHERE和HAVING语法中的子查询块称为嵌套子查询,出现在FROM语法后的子查询块称为内联视图或派生表。
在前文 《数据库查询:解锁数据宝藏的魔法之钥》 中,我们探讨了数据库查询的基础知识和技巧。本篇文章将带您迈入更深的数据库查询领域,深入研究多表联查和子查询的奥秘。多表联查使您能够跨越不同数据表,将信息融合在一起,解锁更全面的数据视角。而子查询则是查询中的查询,为复杂数据问题提供了简洁而强大的解决方案。
例如:select user_id from usertable where mobile_no in (select mobile_no from mobile where mobile_id = '10086');
指出MySQL能使用哪个索引在表中找到记录,查询涉及到的字段上若存在索引,则该索引将被列出,但不一定被查询使用(该查询可以利用的索引,如果没有任何索引显示 null)
提到复杂查询,MYSQL 头疼的旅程就开始了,当然优化的方法和其他的数据监控也不大同,MYSQL的语句优化属于发散性思维,只要你能用上的方法都可以,可不限制于数据库本身的语句优化。所以MYSQL的优化好像是一个讲不完的故事。
MySQL EXPLAIN详解:http://www.jianshu.com/p/ea3fc71fdc45
经过上一篇 where field in (...) 的开场准备,本文正式开启子查询系列,这个系列会介绍子查询的各种执行策略,计划包括以下主题:
上篇文章说了统计数据可以用show table status和show index from 表名查看,可以存着永久性和非永久性,innodb_stats_persistent控制着是否开启永久性,innoDb_stats_persistent_sample_pages和innoDB_stats_transient_sample_pages可以控制采集页面统计,innoDb_stats_auto_recalc控制是否自动计算,都可以在创建表的时候设置。
分别是id,select_type,table、type,partitions,possible_keys,key,key_len,ref,rows,Extra,下面对这些字段出现的可能进行解释:
执行计划是SQL语句经过查询分析器后得到的 抽象语法树 和 相关表的统计信息 作出的一个查询方案,这个方案是由查询优化器自动分析产生的。由于是动态数据采样统计分析出来的结果,所以可能会存在分析错误的情况,也就是存在执行计划并不是最优的情况。
2、多表关联或者表内字段关联时,或做相似功能判断时,往往会使用子查询来解决相应问题。
最近,发现业务线程卡死在读取数据库(MySQL 5.7),数据库CPU飙升到了100%,经过定位发现是下面这样一个SQL(由用户触发的查询,可以理解为查看这个群组的所有用户买过哪些商品)导致的:
MySQL 可以很好的支持大数据量的存取,但是一般说来,数据库中的表越小,在它上面执行的查询也就会越快。因此,在创建表的时候,为了获得更好的性能,我们可以将表中字段的宽度设得尽可能小。例如,在定义邮政编码这个字段时,如果将其设置为CHAR(255),显然给数据库增加了不必要的空间,甚至使用VARCHAR这种类型也是多余的,因为CHAR(6)就可以很好的完成任务了。同样的,如果可以的话,我们应该使用MEDIUMINT而不是BIGIN来定义整型字段。
根据表、列、索引和WHERE子句中的条件的详细信息,MySQL优化器考虑了许多技术来有效地执行SQL查询中涉及的查找。对一个巨大表的查询可以在不读取所有行的情况下执行;涉及多个表的联接可以在不比较每个行组合的情况下执行。「优化器选择执行最有效查询的操作集称为“查询执行计划(query execution plan)”,也称为EXPLAIN计划。」
MySql Explain是对SQL进行性能优化不可或缺的工具,通过他我们可以对SQL进行一定的分析和性能优化,降低线上业务因慢查询造成的性能损失。
领取专属 10元无门槛券
手把手带您无忧上云