標籤:des blog 使用 資料 art ar div sql
子查詢的位置:
select 中、from 後、where 中.group by 和order by 中無實用意義。
子查詢分為如下幾類:
1,標量子查詢:返回單一值的標量,最簡單的形式。
2,列子查詢:返回的結果集是 N 行一列。
3,行子查詢:返回的結果集是一行 N 列。
4,表子查詢:返回的結果集是 N 行 N 列。
可以使用的操作符:= > < >= <= <> ANY IN SOME ALL EXISTS
標量子查詢:是指子查詢返回的是單一值的標量,如一個數字或一個字串,也是子查詢中最簡單的返回形式。
可以使用 = > < >= <= <> 這些操作符對子查詢的標量結果進行比較,通常子查詢的位置在比較式的右側
樣本:
SELECT * FROM article WHERE uid = (SELECT uid FROM user WHERE status=1 ORDER BY uid DESC LIMIT 1)
SELECT * FROM t1 WHERE column1 = (SELECT MAX(column2) FROM t2)
SELECT * FROM article AS t WHERE 2 = (SELECT COUNT(*) FROM article WHERE article.uid = t.uid)
MySQL 列子查詢:指子查詢返回的結果集是 N 行一列,該結果通常來自對錶的某個欄位查詢返回。
可以使用 = > < >= <= <> 這些操作符對子查詢的標量結果進行比較,通常子查詢的位置在比較式的右側
樣本:可以使用 IN、ANY、SOME 和 ALL 操作符,不能直接使用 = > < >= <= <> 這些比較標量結果的操作符。
樣本:
SELECT * FROM article WHERE uid IN(SELECT uid FROM user WHERE status=1)
SELECT s1 FROM table1 WHERE s1 > ANY (SELECT s2 FROM table2)
SELECT s1 FROM table1 WHERE s1 > ALL (SELECT s2 FROM table2)
NOT IN 是 <> ALL 的別名,二者相同。
特殊情況
如果 table2 為空白表,則 ALL 後的結果為 TRUE;
如果子查詢返回如 (0,NULL,1) 這種儘管 s1 比返回結果都大,但有空行的結果,則 ALL 後的結果為 UNKNOWN 。
注意:對於 table2 空表的情況,下面的語句均返回 NULL:
SELECT s1 FROM table1 WHERE s1 > (SELECT s2 FROM table2)
SELECT s1 FROM table1 WHERE s1 > ALL (SELECT MAX(s1) FROM table2)
MySQL 行子查詢:指子查詢返回的結果集是一行 N 列,該子查詢的結果通常是對錶的某行資料進行查詢而返回的結果集。
例子:
SELECT * FROM table1 WHERE (1,2) = (SELECT column1, column2 FROM table2)
註:(1,2) 等同於 row(1,2)
SELECT * FROM article WHERE (title,content,uid) = (SELECT title,content,uid FROM blog WHERE bid=2)
MySQL 表子查詢:指子查詢返回的結果集是 N 行 N 列的一個表資料。
例子:
SELECT * FROM article WHERE (title,content,uid) IN (SELECT title,content,uid FROM blog)
子查詢最佳化:
很多查詢中需要使用子查詢。使用子查詢可以一次性的完成很多邏輯上需要多個步驟才能完成的SQL操作,同時也可以避免事務或者表鎖死。子查詢可以使查詢語句很靈活,但子查詢的執行效率不高。子查詢時,MySQL需要為內層查詢語句的查詢結果建立一個暫存資料表。然後外層查詢語句再暫存資料表中查詢記錄。查詢完畢後,MySQL需要撤銷這些暫存資料表。因此,子查詢的速度會受到一定的影響。如果查詢的資料量比較大,這種影響就會隨之增大。在MySQL中可以使用串連查詢來替代子查詢。串連查詢不需要建立暫存資料表,其速度比子查詢要快。
使用串連(JOIN)來代替子查詢
如:
例子1:
SELECT * FROM t1
WHERE t1.a1 NOT in (SELECT a2 FROM t2 )
最佳化後:
SELECT * FROM t1
LEFT JOIN t2 ON t1.a1=t2.a2
WHERE t2.a2 IS NULL
例子2:
SELECT * FROM article WHERE (title,content,uid) IN (SELECT title,content,uid FROM blog)
最佳化後:
SELECT * FROM article
inner join blog
on (article.title=blog.title AND article.content=blog.content AND article.uid=blog.uid)
不能最佳化的子查詢:
1、mysql不支援子查詢合并和彙總函式子查詢最佳化,mariadb對彙總函式子查詢進行物化最佳化;
2、mysql不支援from子句子查詢最佳化,mariadb對from子句子查詢進行子查詢上拉最佳化;
3、mysql和mariadb對子查詢展開提供有限的支援,如對主鍵的操作才能進行上拉子查詢最佳化;
4、mysql不支援exists子查詢最佳化,mariadb對exists關聯子查詢進行半串連最佳化,對exists非關聯子查詢沒有進一步進行最佳化;
5、mysql和mariadb不支援not exists子查詢最佳化;
6、mysql和mariadb對in子查詢,對滿足半串連語義的查詢進行半串連最佳化,再基於代價評估進行最佳化,兩者對半串連的代價評估選擇方式有差異;
7、mysql不支援not in子查詢最佳化,mariadb對非關聯not in子查詢使用物化最佳化,對關聯not in子查詢不做最佳化;
8、mysql和mariadb對>all非關聯子查詢使用max函數,<all非關聯子查詢使用min函數,對=all和非關聯子查詢使用exists最佳化;
9、對>some和>any非關聯子查詢使用min函數,對<some和<any非關聯子查詢使用max函數,=any和=some子查詢使用半串連進行最佳化,對>some和>any關聯子查詢以及<some和<any關聯子查詢只有exists最佳化。