日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

mysql多表 性能_Mysql 多表联合查询效率分析及优化

發(fā)布時間:2023/12/2 数据库 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mysql多表 性能_Mysql 多表联合查询效率分析及优化 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

1. 多表連接類型

1. 笛卡爾積(交叉連接)在MySQL中可以為CROSS JOIN或者省略CROSS即JOIN,或者使用','? 如:

SELECT*FROMtable1CROSSJOINtable2

SELECT*FROMtable1JOINtable2

SELECT*FROMtable1,table2

由于其返回的結(jié)果為被連接的兩個數(shù)據(jù)表的乘積,因此當(dāng)有WHERE, ON或USING條件的時候一般不建議使用,因為當(dāng)數(shù)據(jù)表項目太多的時候,會非常慢。一般使用LEFT [OUTER] JOIN或者RIGHT [OUTER] JOIN

2.???內(nèi)連接INNER JOIN在MySQL中把INNER JOIN叫做等值連接,即需要指定等值連接條件在MySQL中CROSS和INNER JOIN被劃分在一起。 join_table: table_reference [INNER | CROSS] JOIN table_factor [join_condition]

3. MySQL中的外連接,分為左外連接和右連接,即除了返回符合連接條件的結(jié)果之外,還要返回左表(左連接)或者右表(右連接)中不符合連接條件的結(jié)果,相對應(yīng)的使用NULL對應(yīng)。

例子:

user表:

id | name

———

1 | libk

2 | zyfon

3 | daodao

user_action表:

user_id | action

—————

1 | jump

1 | kick

1 | jump

2 | run

4 | swim

sql:

selectid,name,actionfromuserasu

leftjoinuser_action?aonu.id?=?a.user_id

result:

id | name??? | action

——————————–

1? | libk?? ????? | jump?????????? ①

1? | libk??????? ?| kick?????? ????? ②

1 ?| libk?? ????? | jump????????? ?③

2 ?| zyfon???? ?| run????????? ???? ④

3? | daodao | null???????????? ⑤

分析:

注意到user_action中還有一個user_id=4, action=swim的紀錄,但是沒有在結(jié)果中出現(xiàn),

而user表中的id=3, name=daodao的用戶在user_action中沒有相應(yīng)的紀錄,但是卻出現(xiàn)在了結(jié)果集中

因為現(xiàn)在是left join,所有的工作以left為準.

結(jié)果1,2,3,4都是既在左表又在右表的紀錄,5是只在左表,不在右表的紀錄

工作原理:

從左表讀出一條,選出所有與on匹配的右表紀錄(n條)進行連接,形成n條紀錄(包括重復(fù)的行,如:結(jié)果1和結(jié)果3),如果右邊沒有與on條件匹配的表,那連接的字段都是null.然后繼續(xù)讀下一條。

引申:

我們可以用右表沒有on匹配則顯示null的規(guī)律, 來找出所有在左表,不在右表的紀錄, 注意用來判斷的那列必須聲明為not null的。

如:

sql:

selectid,name,actionfromuserasu

leftjoinuser_action?aonu.id?=?a.user_id

wherea.user_idisNULL

(注意:

1.列值為null應(yīng)該用is null 而不能用=NULL

2.這里a.user_id 列必須聲明為 NOT NULL 的.

)上面sql的result:

id | name | action

————————–

3 | daodao | NULL

——————————————————————————–

一般用法:

a. LEFT [OUTER] JOIN:

除了返回符合連接條件的結(jié)果之外,還需要顯示左表中不符合連接條件的數(shù)據(jù)列,相對應(yīng)使用NULL對應(yīng)

SELECTcolumn_nameFROMtable1LEFT[OUTER]JOINtable2ONtable1.column=table2.column

b. RIGHT [OUTER] JOIN:

RIGHT與LEFT JOIN相似不同的僅僅是除了顯示符合連接條件的結(jié)果之外,還需要顯示右表中不符合連接條件的數(shù)據(jù)列,相應(yīng)使用NULL對應(yīng)

SELECTcolumn_nameFROMtable1RIGHT[OUTER]JOINtable2ONtable1.column=table2.column

Tips:

1. on a.c1 = b.c1 等同于 using(c1)2. INNER JOIN 和 , (逗號) 在語義上是等同的

3. 當(dāng) MySQL 在從一個表中檢索信息時,你可以提示它選擇了哪一個索引。

如果 EXPLAIN 顯示 MySQL 使用了可能的索引列表中錯誤的索引,這個特性將是很有用的。

通過指定 USE INDEX (key_list),你可以告訴 MySQL 使用可能的索引中最合適的一個索引在表中查找記錄行。

可選的二選一句法 IGNORE INDEX (key_list) 可被用于告訴 MySQL 不使用特定的索引。如:

mysql>SELECT*FROMtable1?USEINDEX(key1,key2)

->?WHEREkey1=1ANDkey2=2ANDkey3=3;

mysql>?SELECT*FROMtable1IGNOREINDEX(key3)

->?WHEREkey1=1ANDkey2=2ANDkey3=3;

2. 表連接的約束條件

添加顯示條件WHERE, ON, USING

1. WHERE子句

mysql>

SELECT*FROMtable1,table2WHEREtable1.id=table2.id;

2. ON

mysql>

SELECT*FROMtable1LEFTJOINtable2ONtable1.id=table2.id;

SELECT*FROMtable1LEFTJOINtable2ONtable1.id=table2.id

LEFTJOINtable3ONtable2.id=table3.id;

3. USING子句,如果連接的兩個表連接條件的兩個列具有相同的名字的話可以使用USING

例如:

SELECT FROM LEFT JOIN USING ()

連接多于兩個表的情況舉例:

mysql>

SELECTartists.Artist,?cds.title,?genres.genre

FROMcds

LEFTJOINgenres?N?cds.genreID?=?genres.genreID

LEFTJOINartistsONcds.artistID?=?artists.artistID;

或者 mysql>

SELECTartists.Artist,?cds.title,?genres.genre

FROMcds

LEFTJOINgenresONcds.genreID?=?genres.genreID

LEFTJOINartists?->ONcds.artistID?=?artists.artistID

WHERE(genres.genre?='Pop');

--------------------------------------------

另外需要注意的地方 在MySQL中涉及到多表查詢的時候,需要根據(jù)查詢的情況,想好使用哪種連接方式效率更高。

1. 交叉連接(笛卡爾積)或者內(nèi)連接 [INNER | CROSS] JOIN

2. 左外連接LEFT [OUTER] JOIN或者右外連接RIGHT [OUTER] JOIN 注意指定連接條件WHERE, ON,USING.

3. MySQL如何優(yōu)化LEFT JOIN和RIGHT JOIN

在MySQL中,A LEFT JOIN B join_condition執(zhí)行過程如下:

1)·? 根據(jù)表A和A依賴的所有表設(shè)置表B。

2)·??根據(jù)LEFT JOIN條件中使用的所有表(除了B)設(shè)置表A。

3)·???LEFT JOIN條件用于確定如何從表B搜索行。(換句話說,不使用WHERE子句中的任何條件)。

4)·? 可以對所有標準聯(lián)接進行優(yōu)化,只是只有從它所依賴的所有表讀取的表例外。如果出現(xiàn)循環(huán)依賴關(guān)系,MySQL提示出現(xiàn)一個錯誤。

5)· 進行所有標準WHERE優(yōu)化。

6)· 如果A中有一行匹配WHERE子句,但B中沒有一行匹配ON條件,則生成另一個B行,其中所有列設(shè)置為NULL。

7)· 如果使用LEFT JOIN找出在某些表中不存在的行,并且進行了下面的測試:WHERE部分的col_name IS

NULL,其中col_name是一個聲明為 NOT NULL的列,MySQL找到匹配LEFT

JOIN條件的一個行后停止(為具體的關(guān)鍵字組合)搜索其它行。

RIGHT JOIN的執(zhí)行類似LEFT JOIN,只是表的角色反過來。

聯(lián)接優(yōu)化器計算表應(yīng)聯(lián)接的順序。LEFT JOIN和STRAIGHT_JOIN強制的表讀順序可以幫助聯(lián)接優(yōu)化器更快地工作,因為檢查的表交換更少。請注意這說明如果執(zhí)行下面類型的查詢,MySQL進行全掃描b,因為LEFT JOIN強制它在d之前讀取:

SELECT*

FROMa,bLEFTJOINcON(c.key=a.key)LEFTJOINdON(d.key=a.key)

WHEREb.key=d.key;

在這種情況下修復(fù)時用a的相反順序,b列于FROM子句中:

SELECT*

FROMb,aLEFTJOINcON(c.key=a.key)LEFTJOINdON(d.key=a.key)

WHEREb.key=d.key;

MySQL可以進行下面的LEFT JOIN優(yōu)化:如果對于產(chǎn)生的NULL行,WHERE條件總為假,LEFT JOIN變?yōu)槠胀?lián)接。

例如,在下面的查詢中如果t2.column1為NULL,WHERE 子句將為false:

SELECT*FROMt1LEFTJOINt2ON(column1)WHEREt2.column2=5;

因此,可以安全地將查詢轉(zhuǎn)換為普通聯(lián)接:

SELECT*FROMt1,?t2WHEREt2.column2=5ANDt1.column1=t2.column1;

這樣可以更快,因為如果可以使查詢更佳,MySQL可以在表t1之前使用表t2。為了強制使用表順序,使用STRAIGHT_JOIN。

創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎

總結(jié)

以上是生活随笔為你收集整理的mysql多表 性能_Mysql 多表联合查询效率分析及优化的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。