OceanBase 查詢和子查詢概述

2021-06-09 17:30 更新

查詢(SQL)是指數(shù)據(jù)庫中用來獲取數(shù)據(jù)的方式,它可搭配條件限制的子句(如 WHERE),排列順序的子句(如 ORDER BY)等語句來獲取查詢結(jié)果。子查詢是指嵌套在一個(gè)上層查詢中的查詢。上層的查詢一般被稱為父查詢或外層查詢。子查詢的結(jié)果作為輸入傳遞回“父查詢”或“外部查詢”。父查詢將這個(gè)值結(jié)合到計(jì)算中,以便確定最后的輸出。SQL 語言允許多層嵌套查詢,即一個(gè)子查詢中還可以嵌套其他子查詢。同時(shí),子查詢可以出現(xiàn)在 SQL 語句中的各種子句中,比如 SELECT 語句,F(xiàn)ROM 語句,WHERE 語句等。

子查詢

在數(shù)據(jù)庫中,子查詢可以分成有依賴關(guān)系的子查詢和沒有依賴關(guān)系的子查詢。有依賴關(guān)系的子查詢是指該子查詢的執(zhí)行依賴了外部查詢的變量,所以這種子查詢通常會(huì)被計(jì)算多次。沒有依賴關(guān)系的子查詢是指該子查詢的執(zhí)行不依賴外部查詢的變量, 這種子查詢一般只需要計(jì)算一次。下面分別展示了一個(gè)沒有依賴關(guān)系的子查詢和一個(gè)有依賴關(guān)系的子查詢。

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)

-- 沒有依賴關(guān)系的子查詢
obclient> select * from t1 where t1.a in (select t2.a from t2);
Empty set (0.01 sec)

-- 有依賴關(guān)系的子查詢,子查詢中用到了外層查詢變量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)

子查詢展開是數(shù)據(jù)庫的一種優(yōu)化策略,它把一些子查詢置于外層的父查詢中,其實(shí)質(zhì)是把某些子查詢轉(zhuǎn)化為等價(jià)的多表連接操作。這種策略帶來的一個(gè)明顯的好處就是,有些訪問路徑,連接方法和連接順序可能被有效的利用,使得查詢語句的層次盡可能的減少。下面展示了一個(gè)子查詢展開的例子,即子查詢被改寫成了連接語句。

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)

--- 有依賴關(guān)系的子查詢被展開改寫成連接
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)


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)