日本熟妇hd丰满老熟妇,中文字幕一区二区三区在线不卡 ,亚洲成片在线观看,免费女同在线一区二区

子查詢折疊是將SQL語(yǔ)句中多個(gè)子查詢根據(jù)某種規(guī)則進(jìn)行折疊,以減少SQL語(yǔ)句中子查詢的數(shù)量,從而加快SQL語(yǔ)句執(zhí)行速率的一種子查詢優(yōu)化手段。本文介紹了子查詢折疊的背景知識(shí)、子查詢折疊的折疊原理、使用方法以及示例等內(nèi)容。

背景知識(shí)

子查詢類型

PolarDB MySQL版支持的子查詢類型見下表:

子查詢類型

算子關(guān)鍵字

比較算子

備注

EXISTS

EXISTSNOT EXISTS

無(wú)

無(wú)

IN

INNOT IN

無(wú)

無(wú)

ANY

無(wú)

=、!=、<、<=、<、>=

WHERE t.a > ANY(select t2.a ...)

ALL

無(wú)

=、!=、<、<=、<、>=

WHERE t.a < ALL(select t2.a ...)

單行標(biāo)量子查詢

WHERE t.a < (SELECT MIN(t2.a) ...),子查詢折疊功能不考慮此子查詢類型。

  • 同類型子查詢:如果子查詢類型與對(duì)應(yīng)的算子關(guān)鍵字一致,則稱之為同類型子查詢。如兩個(gè)子查詢都是EXISTS,或者兩個(gè)子查詢都是> ANY,則為同類型子查詢。

  • 互斥子查詢:如果子查詢類型與對(duì)應(yīng)的算子關(guān)鍵字語(yǔ)義相反,則稱之為互斥子查詢。如EXISTSNOT EXISTS即為一對(duì)互斥子查詢,INNOT IN為一對(duì)互斥子查詢。更多互斥子查詢參考如下表:

    子查詢

    互斥子查詢

    EXISTS

    NOT EXISTS

    IN

    NOT IN

    = ANY

    != ALL

    != ANY

    = ALL

    < ANY

    >= ALL> ALL

    <= ANY

    > ALL

    > ANY

    <= ALL< ALL

    >= ANY

    < ALL

子查詢包含關(guān)系

子查詢的右側(cè)結(jié)果集是一個(gè)集合。集合有三種包含關(guān)系:左子集右子集相等。如果集合沒(méi)有包含關(guān)系,則稱之為不可比較。下文以左子集為例進(jìn)行介紹。

左子集:若子查詢左側(cè)的集合是右側(cè)集合的子集,則稱為左子集。示例如下:

SELECT a
FROM t
WHERE EXISTS (
		SELECT /*+ subq1 */ t2.a
		FROM t2
		WHERE t2.a > 10
	)
	AND EXISTS (
		SELECT /*+ subq2 */ t2.a
		FROM t2
	)

從上述示例中可以看出,左側(cè)subq1的條件更嚴(yán)格,結(jié)果集更小,是右側(cè)subq2集合的子集,所以稱為左子集。

子查詢折疊功能概述

    說(shuō)明

    折疊的對(duì)象可以出現(xiàn)在WHEREHAVINGJOIN ON條件的任何位置上,子查詢同時(shí)出現(xiàn)在AND/OR邏輯算子下。

    子查詢可以是EXISTSIN子查詢,ALL或ALL子查詢,支持所有的運(yùn)算算子。

同類型子查詢

如果兩個(gè)子查詢的集合具備包含關(guān)系,則消除其中一個(gè)。具體規(guī)則如下:

子查詢間邏輯運(yùn)算

左右子查詢類型

子查詢包含關(guān)系

限制

折疊類型

折疊說(shuō)明

AND

同為EXISTS、IN、ANY、ALL

左子集、相等

無(wú)

消除

消除右子集,保留左子查詢。 參考示例一:AND條件下子查詢消除

右子集

無(wú)

消除

消除左子集,保留右子查詢。

同為NOT EXISTS、NOT IN、!= ALL

不可比較

  • 僅限SPJ子查詢,或僅含SPJ+HAVING。

  • 僅有WHERE條件或HAVING條件不一致。

合并(不總是最優(yōu))

說(shuō)明

不總是最優(yōu)是指折疊后執(zhí)行效率可能比折疊前差,并不能保證一定是一個(gè)正收益優(yōu)化。實(shí)際上需要配合基于CBQT組件才能決定是否應(yīng)用當(dāng)前規(guī)則。

合并二者的WHEREHAVING條件,合并為一個(gè)新的子查詢。 參考示例一:AND條件下的子查詢合并

OR

同為EXISTS、IN、ANY、ALL

左子集、相等

無(wú)

消除

消除左子集,保留右子集。參考示例二:OR條件下子查詢消除

右子集

無(wú)

消除

消除右子集,保留左子集。

同為EXISTS、IN、ANY

不可比較

  • 僅限SPJ子查詢,或僅含SPJ+HAVING。

  • 僅有WHERE條件或HAVING條件不一致。

合并(不總是最優(yōu))

合并二者的WHEREHAVING條件,合并為一個(gè)新的子查詢。 參考示例二:OR條件下的子查詢合并

互斥子查詢

如果兩個(gè)子查詢的集合具備包含關(guān)系,依賴于邏輯運(yùn)算上下文可以整體改寫為TRUEFALSE,或者將兩個(gè)子查詢合二為一,生成一個(gè)新的子查詢。具體規(guī)則如下:

子查詢間邏輯運(yùn)算

左右子查詢類型

子查詢包含關(guān)系

限制

折疊類型

折疊說(shuō)明

AND

  • EXISTS與NOT EXISTS

  • IN與NOT IN

左子集、相等

無(wú)

消除

AND條件改寫為FALSE

參考示例一:EXISTS互斥類型沖突

EXISTS與NOT EXISTS

右子集

  • 子查詢的查詢塊不能是UNION

  • WHERE條件不同,其余部分相同。

  • 子查詢內(nèi)部支持存在嵌套子查詢。

合并(不總是最優(yōu))

合并集合,增加HAVING SUM(CASE WHEN extra_cond THEN 1 ELSE 0 END) ==0 條件。

參考示例四:EXISTS互斥子查詢合并

  • !=ANY與=ALL

  • <ANY與>=ALL或 >ALL

  • <=ANY與>ALL

  • >ANY與<=ALL或 <ALL

  • >=ANY與<ALL

左子集、相等

無(wú)

消除

AND條件改寫為FALSE

參考示例二:ANY或ALL互斥類型沖突

  • IN與NOT IN

  • =ANY與!=ALL

右子集

  • 子查詢的查詢塊不能是UNION

  • WHEREHAVING條件不同,其余部分相同。

  • 子查詢內(nèi)部支持存在嵌套子查詢。

合并(總是最優(yōu))

合并集合,增加LNNVL算子

折疊總是最優(yōu),默認(rèn)折疊。

參考示例五:ANY或ALL互斥子查詢合并

OR

EXISTS與NOT EXISTS

右子集

無(wú)

消除

將OR條件改寫為TRUE

參考示例三:OR條件下EXISTS查詢消除

使用前提

集群版本需為PolarDB MySQL版8.0版本且修訂版本需為8.0.2.2.23或以上。如何查看集群版本,請(qǐng)參見查詢版本號(hào)

使用方法

您可以通過(guò)將參數(shù)loose_polar_optimizer_switch的值設(shè)置為coalesce_subquery=on來(lái)開啟子查詢折疊功能,以及將參數(shù)force_coalesce_subquery的值設(shè)置為ON來(lái)開啟子查詢合并功能。設(shè)置參數(shù)值的具體操作請(qǐng)參見設(shè)置集群參數(shù)和節(jié)點(diǎn)參數(shù)

參數(shù)名稱

級(jí)別

描述

loose_polar_optimizer_switch

Global

僅開啟或關(guān)閉子查詢折疊功能。默認(rèn)不做子查詢合并。

取值范圍如下:

  • coalesce_subquery=on:開啟子查詢折疊功能。

  • coalesce_subquery=off:關(guān)閉子查詢折疊功能。

force_coalesce_subquery

Global

開啟或關(guān)閉子查詢合并功能,子查詢折疊規(guī)則表格中的不總是最優(yōu)折疊會(huì)強(qiáng)制執(zhí)行。

取值范圍如下:

  • OFF(默認(rèn)值):關(guān)閉子查詢合并功能。

  • ON:開啟子查詢合并功能。

說(shuō)明
  • 您可以在會(huì)話中設(shè)置該參數(shù)的值。示例如下:

    SET force_coalesce_subquery=ON;
  • 您也可以使用HINT語(yǔ)法指定需要折疊的子查詢。示例如下:

    DESC SELECT /*+SUBQUERY_COALESCE(qb1, qb2) SUBQUERY_COALESCE(qb3, qb4) */  * FROM t1 LEFT JOIN t2 ON t1.a = any (SELECT  /*+ QB_NAME(qb1) */ a FROM t2 ) AND
    t1.a != ALL (SELECT  /*+ QB_NAME(qb2) */ a FROM t2 WHERE  a <100) HAVING  t1.b = ANY (SELECT  /*+ QB_NAME(qb3) */  b FROM t2 ) AND
    t1.b != ALL (SELECT  /*+ QB_NAME(qb4) */  b FROM t2 WHERE  b <1);

示例

同類型子查詢消除

示例一:AND條件下子查詢消除

SELECT * FROM t1 WHERE EXISTS (SELECT 1 FROM t2 WHERE c2 = 0)  --子查詢1
	AND EXISTS (SELECT 1 FROM t2); 		              --子查詢2

其中,子查詢1是子查詢2的子集,因此直接消除子查詢2。消除后的SQL語(yǔ)句如下:

SELECT * FROM t1 WHERE EXISTS (SELECT 1 FROM t2 WHERE c2 = 0);

示例二:OR條件下子查詢消除

SELECT * FROM t1 WHERE EXISTS (SELECT 1 FROM t2 WHERE c2 = 0)  --子查詢1
	or EXISTS (SELECT 1 FROM t2);		              --子查詢2

其中,子查詢1被消除掉,OR條件改寫為EXISTS (SELECT 1 FROM t2),保留大集合。消除后的SQL語(yǔ)句如下:

SELECT * FROM t1 WHERE EXISTS (SELECT 1 FROM t2);

同類型子查詢合并

示例一:AND條件下的子查詢合并

SELECT * FROM t1 WHERE NOT EXISTS (SELECT t1.a AS f FROM t1 WHERE a >10 AND b < 10)
AND NOT EXISTS (SELECT a FROM t1 WHERE a > 10  AND c <3);

合并后的SQL語(yǔ)句如下:

SELECT * FROM t1 WHERE NOT EXISTS (SELECT t1.a AS f FROM t1 WHERE a >10 AND (b < 10 OR c <3);

示例二:OR條件下的子查詢合并

SELECT * FROM t1 WHERE EXISTS (SELECT t1.a AS f FROM t1 WHERE a >10 AND b < 10)
OR EXISTS (SELECT a FROM t1 WHERE a > 10 AND c <3);

合并后的SQL語(yǔ)句如下:

SELECT * FROM t1 WHERE EXISTS (SELECT t1.a AS f FROM t1 WHERE a >10 AND (b < 10 OR c <3);

互斥子查詢消除

示例一:EXISTS互斥類型沖突

適用場(chǎng)景EXISTSNOT EXISTSINNOT IN

SELECT * FROM t1 WHERE EXISTS (SELECT 1 FROM t2 WHERE c1 = 0)  --子查詢1
      AND NOT EXISTS (SELECT 1 FROM t2); 		--子查詢2

AND條件改寫為FALSE,改寫后的SQL語(yǔ)句如下:

SELECT * FROM t1 WHERE false;

示例二:ANY或ALL互斥類型沖突

適用場(chǎng)景

  • >ANY<ALL<=ALL

  • <ANY>ALL>=ALL

SELECT * FROM t1 WHERE t1.c1 > ANY (SELECT c1 FROM t2 WHERE c1 > 10 AND c2 > 1)
                   AND t1.c1 < ALL (SELECT c1 FROM t2 WHERE  c1 > 10);

AND條件改寫為FALSE,改寫后的SQL語(yǔ)句如下:

SELECT * FROM t1 WHERE false; //ANY是ALL集合的子集

示例三:OR條件下EXISTS查詢消除

SELECT * FROM t1 WHERE exists (SELECT 1 FROM t2 )  --子查詢1
      OR NOT exists (SELECT 1 FROM t2 WHERE c1 = 0);		--子查詢2

將OR條件改寫為TRUE,改寫后的SQL語(yǔ)句如下:

SELECT * FROM t1 WHERE true; //子查詢2是子查詢1的子集

示例四:EXISTS互斥子查詢合并

SELECT * FROM t1 WHERE EXIST (SELECT 1 FROM t2) 	    --子查詢1
	 AND NOT EXIST (SELECT 1 FROM t2 WHERE c2 = 0);      --子查詢2

合并集合,增加HAVING SUM(CASE WHEN extra_cond THEN 1 ELSE 0 END) ==0條件。合并后的SQL語(yǔ)句如下:

SELECT * FROM t1 WHERE EXIST (SELECT 1 FROM t2 HAVING SUM (CASE WHEN extra_cond THEN 1 ELSE 0 END) ==0);
說(shuō)明

合并不總是最優(yōu)的,您需要基于代價(jià)選擇是否進(jìn)行折疊,如確認(rèn)改寫較優(yōu),需將參數(shù)force_coalesce_subquery的值設(shè)置為ON來(lái)開啟子查詢合并功能。

基于TPCH Q21熱數(shù)據(jù),開啟子查詢折疊功能前后的查詢耗時(shí)如下,耗時(shí)短表示改寫更優(yōu):

image

示例五:ANY或ALL互斥子查詢合并

適用場(chǎng)景

  • INNOT IN,并且NOT IN集合更小,是左側(cè)子集。

  • =ANY != ALL ,并且ALL集合更小,是左側(cè)子集。

SELECT * FROM t1 WHERE t1.c1 = ANY (SELECT c1 FROM t2 WHERE c1 > 10) AND
t1.c1 != ALL (SELECT c1 FROM t2 WHERE  c1 > 100);

合并集合,增加LNNVL算子。合并后的SQL語(yǔ)句如下:

SELECT * FROM t1 WHERE t1.c1 = 
ANY (SELECT c1 FROM t2 WHERE c1 > 10 AND LNNVL(c1 >100));