方式(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") ");
這兩種方式如何取舍
但是問題在于,如果是使用了子查詢的話,那么你需要一次進(jìn)程間通信,即 Java 給 MySQL 發(fā)送一次請求,然后 MySQL 查詢完成之后返回數(shù)據(jù)。 但是如果是分開兩次查詢的話,那么網(wǎng)絡(luò)通信的次數(shù)就變成了 1+(第一次結(jié)果集次),對于 MySQL 也好,Java 也好,他們的執(zhí)行速度都是很快的,慢的是他們之間的通信,所以使用子查詢的時候減少了他們之間通信的次數(shù),同時需要發(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次吧,難道我思路錯了
2018-11-27
從性能上看,關(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)表查詢。
2018-12-14
首先,建表
可以看到 我這里給 users 加的索引是 (username,enable) 而不是 (enable)。
然后當(dāng)我們用 explain 去分析你給的第一條 SQL 語句的時候,
就會發(fā)現(xiàn) users 表上面是使用了 `key_username_enable` 的,然后這個時候,根據(jù)索引的最左匹配原則,可以知道, mysql 把 username 這個條件下推了,所以這個時候,MySQL 對于上面的 SQL 語句的執(zhí)行應(yīng)該是類似于以下方式
因此把它分成兩部分來理解應(yīng)該是
------------------------------------------------ 分割線 -------------------------------------------------------------------------------------------
好了, 其實上面的都是廢話來的。
如果你是分開執(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ā)送的東西也少了,所以子查詢會快一點。
2018-12-14
sql運行機(jī)制和java運行機(jī)制不一樣,?sql語句只要配置合理,都是秒級的,甚至是毫秒級的,喜歡這個答案。只是看到有很多程序也存在使用第一種方法。不知道他們是怎么考慮的。既然mybatis可以那么方便的配置查詢語句,貌似很多業(yè)務(wù)層都可以直接寫到SQL語句里了,程序只是負(fù)責(zé)傳參而已
2018-12-11
啊,你說的對,是我把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ù)了……
2018-12-10
我怎么覺得第二種不是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次吧,難道我思路錯了
2018-12-07
我覺得肯定是關(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。
這效率一對比,就什么都不用說了。