codecamp

OceanBase 查询和子查询概述

查询(SQL)是指数据库中用来获取数据的方式,它可搭配条件限制的子句(如 WHERE),排列顺序的子句(如 ORDER BY)等语句来获取查询结果。子查询是指嵌套在一个上层查询中的查询。上层的查询一般被称为父查询或外层查询。子查询的结果作为输入传递回“父查询”或“外部查询”。父查询将这个值结合到计算中,以便确定最后的输出。SQL 语言允许多层嵌套查询,即一个子查询中还可以嵌套其他子查询。同时,子查询可以出现在 SQL 语句中的各种子句中,比如 SELECT 语句,FROM 语句,WHERE 语句等。

子查询

在数据库中,子查询可以分成有依赖关系的子查询和没有依赖关系的子查询。有依赖关系的子查询是指该子查询的执行依赖了外部查询的变量,所以这种子查询通常会被计算多次。没有依赖关系的子查询是指该子查询的执行不依赖外部查询的变量, 这种子查询一般只需要计算一次。下面分别展示了一个没有依赖关系的子查询和一个有依赖关系的子查询。

obclient> create table t1(a int primary key, b int, c int);
Query OK, 0 rows affected (0.09 sec)

obclient> create table t2(a int primary key, b int, c int);
Query OK, 0 rows affected (0.06 sec)

-- 没有依赖关系的子查询
obclient> select * from t1 where t1.a in (select t2.a from t2);
Empty set (0.01 sec)

-- 有依赖关系的子查询,子查询中用到了外层查询变量t1.b
obclient> select * from t1 where t1.a in (select t2.a from t2 where t2.b = t1.b);
Empty set (0.01 sec)

子查询展开(subquery unnesting)

子查询展开是数据库的一种优化策略,它把一些子查询置于外层的父查询中,其实质是把某些子查询转化为等价的多表连接操作。这种策略带来的一个明显的好处就是,有些访问路径,连接方法和连接顺序可能被有效的利用,使得查询语句的层次尽可能的减少。下面展示了一个子查询展开的例子,即子查询被改写成了连接语句。

obclient> create table t1(a int primary key, b int, c int);
Query OK, 0 rows affected (0.09 sec)

obclient> create table t2(a int primary key, b int, c int);
Query OK, 0 rows affected (0.09 sec)

--- 有依赖关系的子查询被展开改写成连接
obclient> explain select * from t1 where t1.a in (select t2.b from t2 where t2.c = t1.c);
| ============================================
|ID|OPERATOR        |NAME |EST. ROWS|COST  |
--------------------------------------------
|0 |MERGE JOIN      |     |9703     |215436|
|1 | TABLE SCAN     |t1   |100000   |64066 |
|2 | SORT           |     |10001    |129621|
|3 |  SUBPLAN SCAN  |VIEW1|10001    |111242|
|4 |   HASH DISTINCT|     |10001    |109862|
|5 |    TABLE SCAN  |t2   |100000   |64066 |
============================================

Outputs & filters:
-------------------------------------
  0 - output([t1.a], [t1.b], [t1.c]), filter(nil),
      equal_conds([t1.a = VIEW1.t2.b], [VIEW1.t2.c = t1.c]), other_conds(nil)
  1 - output([t1.c], [t1.a], [t1.b]), filter(nil),
      access([t1.c], [t1.a], [t1.b]), partitions(p0)
  2 - output([VIEW1.t2.b], [VIEW1.t2.c]), filter(nil), sort_keys([VIEW1.t2.b, ASC], [VIEW1.t2.c, ASC])
  3 - output([VIEW1.t2.b], [VIEW1.t2.c]), filter(nil),
      access([VIEW1.t2.b], [VIEW1.t2.c])
  4 - output([t2.b], [t2.c]), filter(nil),
      distinct([t2.b], [t2.c])
  5 - output([t2.c], [t2.b]), filter(nil),
      access([t2.c], [t2.b]), partitions(p0)


OceanBase 其他函数
OceanBase 连接
温馨提示
下载编程狮App,免费阅读超1000+编程语言教程
取消
确定
目录

OceanBase 控制台指南

OceanBase ODC 使用指南

OceanBase Web 版 ODC

OceanBase 客户端版 ODC

OceanBase Connector/J 开发者指南

OceanBase 什么是OceanBase Connector/J

OceanBase SQL 参考(MySQL 模式)

OceanBase SQL 参考(Oracle 模式)

OceanBase 基本元素

OceanBase 数据库对象

OceanBase 函数

OceanBase 单行函数

OceanBase 返回数字的字符串函数

OceanBase 通用比较函数

OceanBase 编码解码函数

OceanBase SQL 调优指南

OceanBase 相关协议

关闭

MIP.setData({ 'pageTheme' : getCookie('pageTheme') || {'day':true, 'night':false}, 'pageFontSize' : getCookie('pageFontSize') || 20 }); MIP.watch('pageTheme', function(newValue){ setCookie('pageTheme', JSON.stringify(newValue)) }); MIP.watch('pageFontSize', function(newValue){ setCookie('pageFontSize', newValue) }); function setCookie(name, value){ var days = 1; var exp = new Date(); exp.setTime(exp.getTime() + days*24*60*60*1000); document.cookie = name + '=' + value + ';expires=' + exp.toUTCString(); } function getCookie(name){ var reg = new RegExp('(^| )' + name + '=([^;]*)(;|$)'); return document.cookie.match(reg) ? JSON.parse(document.cookie.match(reg)[2]) : null; }