第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機(jī)立即綁定

關(guān)聯(lián)表查詢是單表查詢出結(jié)果后再用程序過濾還是直接用SQL語句查詢最終結(jié)果

二者都有利弊吧,要從性能和易讀易懂易維護(hù)各方面考慮,在什么場景下應(yīng)該選哪種關(guān)聯(lián)查詢方式呢

正在回答

6 回答

從性能上看,關(guān)聯(lián)表查詢是為了應(yīng)對大數(shù)據(jù)查詢,減少查詢的基數(shù),靈活的配置主鍵等信息,提高查詢的效率;

從維護(hù)上看,關(guān)聯(lián)表查詢從表名上更容易明白功能的分級,便于閱讀和維護(hù),并且模塊劃分越細(xì),后期越容易擴(kuò)展;

如果是程序開發(fā)初期,使用人群較少,訪問量數(shù)據(jù)量比較少,可以使用單表查詢;但是從長遠(yuǎn)上看,防止訪問量飆升,數(shù)據(jù)量也飆升導(dǎo)致性能變慢的情況發(fā)生,應(yīng)當(dāng)使用關(guān)聯(lián)表查詢。

0 回復(fù) 有任何疑惑可以回復(fù)我~
#1

qq_雙子星深藍(lán)_0 提問者

我的問題還有一個點還沒搞清楚,關(guān)聯(lián)查詢,有兩種方式(1) ResultSet rs1 = stmt.executeQuery("select username from users where enable = 0"); ResultSet rs2 = stmt.executeQuery("select amount from orders where status = “unpay” "); for(rs1) { for(rs2) { if(rs1.username == rs2.username) { } } }
2018-12-03 回復(fù) 有任何疑惑可以回復(fù)我~
#2

qq_雙子星深藍(lán)_0 提問者

方式(2)只用一段關(guān)聯(lián)語句查詢ResultSet rs = stmt.executeQuery("select amount from orders where status = “unpay” and username in ("select username from users where enable = 0") "); 這兩種方式如何取舍
2018-12-03 回復(fù) 有任何疑惑可以回復(fù)我~

首先,建表

create?table?users?(
??id?int?unsigned?not?null?auto_increment,
??username?char?not?null?,
??enable?tinyint?not?null?default?0,
??primary?key?(id)
)ENGINE=InnoDB?default?charset=utf8;
alter?table?users
??add?key?key_username_enable(username,?enable);

create?table?orders?(
??id?int?unsigned?not?null?auto_increment,
??username?char?not?null?,
??status?char(10)?not?null?default?"unpay",
??amount?char(30)?not?null?,
??primary?key?(id)
)ENGINE=InnoDB?default?charset=utf8;

可以看到 我這里給 users 加的索引是 (username,enable) 而不是 (enable)。

然后當(dāng)我們用 explain 去分析你給的第一條 SQL 語句的時候,

select?amount?
??from?orders?
where?
??status="unpay"?
????and?
??username?in?(select?username?from?users?where?enable?=?0);

就會發(fā)現(xiàn) users 表上面是使用了 `key_username_enable` 的,然后這個時候,根據(jù)索引的最左匹配原則,可以知道, mysql 把 username 這個條件下推了,所以這個時候,MySQL 對于上面的 SQL 語句的執(zhí)行應(yīng)該是類似于以下方式

select?amount?
??from?orders?
where?
??status="unpay"?
????and?
??exists?
????(select?orders.username?from?users?
??????where?enable=0?and?users.username=orders.username);

因此把它分成兩部分來理解應(yīng)該是

#?1.
select?amount,username?from?orders?where?status='unpay';
#?2.?
select?username?from?users?where?enable=0?and?username=?;?#這里的?代表上一層傳過來的參數(shù)

------------------------------------------------ 分割線 -------------------------------------------------------------------------------------------

好了, 其實上面的都是廢話來的。

如果你是分開執(zhí)行上面那兩個 SQL 語句,對于 MySQL 來說,他所需要的時間是差不多的,

因為你如果是子查詢,其實他也是先執(zhí)行外部的找出一條數(shù)據(jù),然后在進(jìn)去子查詢里面查詢的,和在 Java 里面分開查詢是一樣的。

但是問題在于,如果是使用了子查詢的話,那么你需要一次進(jìn)程間通信,即 Java 給 MySQL 發(fā)送一次請求,然后 MySQL 查詢完成之后返回數(shù)據(jù)。 但是如果是分開兩次查詢的話,那么網(wǎng)絡(luò)通信的次數(shù)就變成了 1+(第一次結(jié)果集次),對于 MySQL 也好,Java 也好,他們的執(zhí)行速度都是很快的,慢的是他們之間的通信,所以使用子查詢的時候減少了他們之間通信的次數(shù),同時需要發(fā)送的東西也少了,所以子查詢會快一點。

1 回復(fù) 有任何疑惑可以回復(fù)我~
#1

qq_雙子星深藍(lán)_0 提問者

分析的很清楚,謝謝,這就延伸出另一個問題,在你的分析里用子查詢能提升性能,但對于mybats框架來說mapper映射文件通常只是查詢一個張表, 也就是說當(dāng)一個業(yè)務(wù)需要關(guān)聯(lián)多張表的時候那mybatis還是只能分兩次映射分別查詢orders和users之后再用程序來處理最終的結(jié)果 users.username=orders.username,這個你又怎么看呢?
2018-12-17 回復(fù) 有任何疑惑可以回復(fù)我~
#2

慕無忌2563680 回復(fù) qq_雙子星深藍(lán)_0 提問者

不是很懂 `但對于mybatis框架來說mapper映射文件通常只是查詢一個張表` 這句話,如果你在mybatis的mapper文件里面寫了聯(lián)表查詢,那他也是一次查詢而已啊。所以mapper查詢一張表還是多張表還是看你怎么寫啊
2018-12-18 回復(fù) 有任何疑惑可以回復(fù)我~
#3

qq_雙子星深藍(lán)_0 提問者 回復(fù) 慕無忌2563680

“但對于mybatis框架來說。。。”這句的意思是通常mybatis的寫法都是一個mapper對應(yīng)一張表,users.mapper, orders.mapper, users.mapper只查詢users的數(shù)據(jù),orders.mapper查詢orders的數(shù)據(jù),大部分例子都是這樣,甚至慕課網(wǎng)上的一些項目都是在各自mapper查詢出單表數(shù)據(jù)之后再用程序處理關(guān)聯(lián)邏輯。這就不太清楚考量的尺度,什么情況下才考慮用一個mapper關(guān)聯(lián)多表查詢?
2018-12-19 回復(fù) 有任何疑惑可以回復(fù)我~
#4

慕無忌2563680 回復(fù) qq_雙子星深藍(lán)_0 提問者

在mapper文件里面什么時候用聯(lián)表查詢這個問題,首先第一個就是在有明顯的包含關(guān)系的時候就會用聯(lián)表查詢,比如說相冊表和圖片表這種(一個相冊包含多個圖片);還有一個就是在比如上面的查詢結(jié)果只有其中一張表的數(shù)據(jù);再還有一個就是比如刪除、更新的時候也會使用聯(lián)表查詢。
2018-12-19 回復(fù) 有任何疑惑可以回復(fù)我~
#5

qq_雙子星深藍(lán)_0 提問者 回復(fù) 慕無忌2563680

謝謝你的回復(fù),學(xué)習(xí)了
2018-12-20 回復(fù) 有任何疑惑可以回復(fù)我~
查看2條回復(fù)

sql運行機(jī)制和java運行機(jī)制不一樣,?sql語句只要配置合理,都是秒級的,甚至是毫秒級的,喜歡這個答案。只是看到有很多程序也存在使用第一種方法。不知道他們是怎么考慮的。既然mybatis可以那么方便的配置查詢語句,貌似很多業(yè)務(wù)層都可以直接寫到SQL語句里了,程序只是負(fù)責(zé)傳參而已

0 回復(fù) 有任何疑惑可以回復(fù)我~

啊,你說的對,是我把sql語句看錯了。

再分析一次,在不考慮緩存的情況下:

先執(zhí)行username in ("select username from users where enable = 0") 這是1000次,返回500的基數(shù)

500 * 1000 = 500000,確實次數(shù)已經(jīng)超過第一種很多了。

但是sql運行機(jī)制和java運行機(jī)制不一樣,如果要比速度,肯定sql要快,根據(jù)我的開發(fā)經(jīng)驗,java很少寫高量級的循環(huán)語句。sql語句只要配置合理,都是秒級的,甚至是毫秒級的。所以肯定是第二種最棒,要不我寫了這么多年前端,也不會來研究數(shù)據(jù)了……


0 回復(fù) 有任何疑惑可以回復(fù)我~

我怎么覺得第二種不是1000+500 這么簡單,select username from users where enable = 0數(shù)據(jù)庫需要跑1000次,select amount from orders where status =“unpay”這里也是1000次,復(fù)合這一句and username in也是要*500次吧,難道我思路錯了

0 回復(fù) 有任何疑惑可以回復(fù)我~

我覺得肯定是關(guān)鍵表查詢效率要高:

假設(shè)username和amount都是1000條數(shù)據(jù),第一種查詢得到500條結(jié)果,第二種也是500條結(jié)果。

第一種方式:除去查詢效率,二維for循環(huán)效率極低,需要對比500*500=250000次,總次數(shù)是1000 +1000 + 250000.

第二種:相當(dāng)于先查詢username的500條組成一個新的表,然后從結(jié)果500條中查詢符合第二個條件的結(jié)果??偞螖?shù)等于1000+500。

這效率一對比,就什么都不用說了。

0 回復(fù) 有任何疑惑可以回復(fù)我~

舉報

0/150
提交
取消

關(guān)聯(lián)表查詢是單表查詢出結(jié)果后再用程序過濾還是直接用SQL語句查詢最終結(jié)果

我要回答 關(guān)注問題
微信客服

購課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號