亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

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

關聯表查詢是單表查詢出結果后再用程序過濾還是直接用SQL語句查詢最終結果

二者都有利弊吧,要從性能和易讀易懂易維護各方面考慮,在什么場景下應該選哪種關聯查詢方式呢

正在回答

6 回答

從性能上看,關聯表查詢是為了應對大數據查詢,減少查詢的基數,靈活的配置主鍵等信息,提高查詢的效率;

從維護上看,關聯表查詢從表名上更容易明白功能的分級,便于閱讀和維護,并且模塊劃分越細,后期越容易擴展;

如果是程序開發初期,使用人群較少,訪問量數據量比較少,可以使用單表查詢;但是從長遠上看,防止訪問量飆升,數據量也飆升導致性能變慢的情況發生,應當使用關聯表查詢。

0 回復 有任何疑惑可以回復我~
#1

qq_雙子星深藍_0 提問者

我的問題還有一個點還沒搞清楚,關聯查詢,有兩種方式(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 回復 有任何疑惑可以回復我~
#2

qq_雙子星深藍_0 提問者

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

首先,建表

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)。

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

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

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

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

因此把它分成兩部分來理解應該是

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

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

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

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

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

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

1 回復 有任何疑惑可以回復我~
#1

qq_雙子星深藍_0 提問者

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

慕無忌2563680 回復 qq_雙子星深藍_0 提問者

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

qq_雙子星深藍_0 提問者 回復 慕無忌2563680

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

慕無忌2563680 回復 qq_雙子星深藍_0 提問者

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

qq_雙子星深藍_0 提問者 回復 慕無忌2563680

謝謝你的回復,學習了
2018-12-20 回復 有任何疑惑可以回復我~
查看2條回復

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

0 回復 有任何疑惑可以回復我~

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

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

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

500 * 1000 = 500000,確實次數已經超過第一種很多了。

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


0 回復 有任何疑惑可以回復我~

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

0 回復 有任何疑惑可以回復我~

我覺得肯定是關鍵表查詢效率要高:

假設username和amount都是1000條數據,第一種查詢得到500條結果,第二種也是500條結果。

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

第二種:相當于先查詢username的500條組成一個新的表,然后從結果500條中查詢符合第二個條件的結果??偞螖档扔?000+500。

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

0 回復 有任何疑惑可以回復我~

舉報

0/150
提交
取消

關聯表查詢是單表查詢出結果后再用程序過濾還是直接用SQL語句查詢最終結果

我要回答 關注問題
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號