mysql 表變數來代替臨 MySQL多表查詢優化

2021-10-18 21:05:51 字數 2894 閱讀 3056

一、多表查詢連線的選擇:

相信這內連線,左連線什麼的大家都比較熟悉了,當然還有左外連線什麼的,基本用不上我就不貼出來了。這圖只是讓大家回憶一下,各種連線查詢。 然後要告訴大家的是,需要根據查詢的情況,想好使用哪種連線方式效率更高。

二、mysql的join實現原理

在mysql 中,只有一種join 演算法,就是大名鼎鼎的nested loop join,他沒有其他很多資料庫所提供的hash join,也沒有sort merge join。顧名思義,nested loop join 實際上就是通過驅動表的結果集作為迴圈基礎資料,然後一條一條的通過該結果集中的資料作為過濾條件到下乙個表中查詢資料,然後合併結果。如果還有第三個參與join,則再通過前兩個表的join 結果集作為迴圈基礎資料,再一次通過迴圈查詢條件到第三個表中查詢資料,如此往復。 ——摘自《mysql 效能調優與架構設計》

三、補充:mysql對sql語句的容錯問題

即在sql語句不完全符合書寫建議的情況,mysql會允許這種情況,盡可能解釋它:

1)一般cross join後面加上where條件,但是用cross join+on也是被解釋為cross join+where;

2)一般內連線都需要加上on限定條件,如上面場景一;如果不加會被解釋為交叉連線;

3)如果連線**使用的是逗號,會被解釋為交叉連線;

注:sql標準中還有union join和natural inner join,mysql不支援,而且本身也沒有多大意義,其實就是為了「健壯」。但是其實結果可以用上面的幾種連線方式得到。

三、超大型資料盡可能盡力不要寫子查詢,使用連線(join)去替換它:

當然,關於這句話,也不一定就全是這樣。

1)因為在大型的資料處理中,子查詢是非常常見的,特別是在查詢出來的資料需要進一步處理的情況,無論是可讀性還是效率上,這時候的子查都是更優。

2)然而在一些特定的場景,可以直接從資料庫讀取就可以的,比如乙個表(a表 a,b,c欄位,需要內部資料交集)join自己的效率必然比放乙個子查在where中快得多。

四、使用聯合(union)來代替手動建立的臨時表

union是會把結果排序的!!!

union查詢:它可以把需要使用臨時表的兩條或更多的select查詢合併的乙個查詢中(即把兩次或多次查詢結果合併起來。)。在客戶端的查詢會話結束的時候,臨時表會被自動刪除,從而保證資料庫整齊、高效。使用union來建立查詢的時候,我們只需要用union作為關鍵字把多個select語句連線起來就可以了,要注意的是所有select語句中的字段數目要想同。

可以來自多張表的資料:多次sql語句取出的列名可以不一致,此時以第乙個sql語句的列名為準。

如果不同的語句中取出的行,有完全相同(這裡表示的是每個列的值都相同),那麼union會將相同的行合併,最終只保留一行。也可以這樣理解,union會去掉重複的行。

如果不想去掉重複的行,可以使用union all。

如果子句中有order by,limit,需用括號()包起來。推薦放到所有子句之後,即對最終合併的結果來排序或篩選。

注意:1、union 結果集中的列名總是等於第乙個 select 語句中的列名

2、union 內部的 select 語句必須擁有相同數量的列。列也必須擁有相似的資料型別。同時,每條 select 語句中的列的順序必須相同

union all的作用和語法:

預設地,union 操作符選取不同的值。如果允許重複的值,請使用 union all。當 all 隨 union 一起使用時(即 union all),不消除重複行。

五、總結

(1)對於要求全面的結果時,我們需要使用連線操作(left join / right join / full join);

(2)應盡量避免在 where 子句中對字段進行 null 值判斷,否則將導致引擎放棄使用索引而進行全表掃瞄,如:

不要以為 null 不需要空間,比如:char(100) 型,在字段建立時,空間就固定了, 不管是否插入值(null也包含在內),都是占用 100個字元的空間的,如果是varchar這樣的變長字段, null 不占用空間。

可以在num上設定預設值0,確保表中num列沒有null值,然後這樣查詢:

select id from t where num = 0

(3)in 和 not in 也要慎用,否則會導致全表掃瞄,如:

對於連續的數值,能用 between 就不要用 in 了:

很多時候用 exists 代替 in 是乙個好的選擇:

(4)盡量使用數字型字段,若只含數值資訊的字段盡量不要設計為字元型,這會降低查詢和連線的效能,並會增加儲存開銷。這是因為引擎在處理查詢和連 接時會逐個比較字串中每乙個字元,而對於數字型而言只需要比較一次就夠了。

(5)盡量使用表變數來代替臨時表。如果表變數包含大量資料,請注意索引非常有限(只有主鍵索引)。

(6)不要以為使用mysql的一些連線操作對查詢有多麼大的改善,其實核心是索引

mysql中 變數 MYSQL中的變數 MySQL

bitscn.com 只記很基礎的知識,細節東西太麻煩了,而且我也用不到。變數分為使用者變數與系統變數。使用者變數 使用者變數與資料庫連線有關,在這個連線中宣告的變數,在連線斷開的時候,就會消失。在此連線中宣告的變數無法在另一連線中使用。使用者變數的變數名的形式為 varname的形式。名字必須以 ...

mysql臨時表僅對當前使用者 mysql臨時表問題

1 使用者上傳txt文件到 2 對txt文件進行處理,得到建立的臨時表 txt文件的時間性很短,只持續3個小時作用,所以選了臨時表 3 使用者輸入不同的操作,根據臨時表查詢後返回相應的結果。比如使用者輸入查詢名字叫張三,就返回張三的資訊,輸入李四就返回李四的資訊 4 使用者退出登入後,或關閉網頁後,...

mysql表檔案建立 php檔案建立mysql的表

乙個php檔案,裡面內容是建表語句,如下,怎麼操作這個php檔案才能在mysql中建表啊?createtableifnotexists category id.乙個php檔案,裡面內容是建表語句,如下,怎麼操作這個php檔案才能在mysql中建表啊?create table if not exist...