-
1 # 程式設計師小助手
-
2 # 一隻笨貓
這個得看情況,一般資料不大的情況下多表連線查詢和多次單表查詢的效率差不多。如果資料量足夠大,那肯定是多次單表查詢的效率更高。在很多大的公司裡面,都會禁用多表連線查詢,原因就是一旦資料量足夠大的時候多表連線查詢效率會很慢,而且不利於分庫分表的查詢最佳化。那麼看一下下面這個例子。
兩種查詢方式的比較我這裡有一個數據庫,我們拿裡面的客戶表和地區表做兩種查詢的對比。使用者表資料是31萬條,地區表3511條。
1. 使用連表查詢成都市的客戶總數
2.使用多次單表查詢客戶總數
可以看到,查詢出來的結果都是一樣,但是第一種的連表查詢用了0.67秒中,而第二種多次單表查詢一共用時0.14秒。這個對比已經是很明顯了吧。
雖然這只是一個很簡單的例子,但是對比結果是非常明顯的。在實際應用中可能會更復雜、資料更多,如果還使用連表查詢時非常慢的,而且還消耗伺服器資源。
所以現在在很多大了公司明確要求禁止使用join查詢,比如阿里、騰訊就明確規定禁用三表以上的join查詢。
總結一下,單表查詢的優點1. 多次單表查詢,讓快取的效率更高。
許多應用程式可以方便地快取單表查詢對應的結果物件。另外對於MySQL的查詢快取來說,如果關聯中的某個表發生了變化,那麼就無法使用查詢快取了,而拆分後,如果某個表很少改變,那麼基於該表的查詢就可以重複利用查詢快取結果了。
2. 將查詢分解後,執行單個查詢可以減少鎖的競爭。
3. 在應用層做關聯,更容易對資料庫進行拆分,更容易做到高效能和可擴充套件。
4. 查詢本身效率也可能會有所提升。
5. 可以減少冗餘記錄的查詢。
6. 在應用中實現了雜湊關聯,而不是使用MySQL的巢狀環關聯,某些場景雜湊關聯的效率更高很多。
7. 單表查詢有利於後期資料量大了分庫分表,如果聯合查詢的話,一旦分庫,原來的sql都需要改動。
8. 很多大公司明確規定禁用join,因為資料量大的時候查詢確實很慢
所以在資料量不大的情況下,兩種方式的查詢都沒什麼明顯的差別,使用多表連線查詢更方便。但是在資料量足夠大幾十萬、幾百萬甚至上億的資料,或者在一些高併發、高效能的應用中,一般建議使用單表查詢。
-
3 # 科技世界雜談
如果資料量小的表,這樣的設計意義不大,而且當然是單錶速度快。若在大資料量情況下,設計非常有意義。在多表連線中注意資料的條目和外健,避免出行大量冗餘資料導致效能下降。下面我以Oracle講講資料查詢的整個過程技術。
由於資料分佈到資料塊,在大量資料設計中可以將資料儲存於多個數據塊,在高併發程序的隨機訪問的情況下,能有效減少塊衝突 同樣的資料需要更多的資料塊來儲存,由於資料塊的塊頭元資訊大小固定,所以需要更多的空間來儲存塊頭元資訊。行長度過大容易導致行連線,從而導致Oracle獲取資料塊的效率降低 ,在行長度固定的前提下,單塊能夠儲存更多的資料行,也就意味著Oracle一次I/O能讀取更多的資料行。適合連續順序讀或者存放大物件資料(如LOB資料) 由於大資料塊可以存放更多的索引葉節點資訊,容易引起爭用,所以大資料塊不適合存放索引葉節點資訊。
大量資料表的資料庫引數設定DB_FILE_MULTIBLOCK_READ_COUNT表示Oracle一次順序I/O讀操作最多能讀取的資料塊塊數。該引數的預設值隨作業系統的不同而不同。在全表掃描或者索引快速掃描比較多的系統中(如DSS系統),建議將該值設定得較大。但是DB_FILE_MULTIBLOCK_READ_COUNT引數受操作最大單次I/O大小的限制,大多數作業系統單次讀操作的大小不能超過1MB,這也就意味著在8KB資料塊大小的情況下,該引數最大值為128。值得一提的是,該引數的大小還會影響Oracle CBO對執行計劃的評估,如果設成較大值,Oracle的執行計劃傾向於全表掃描。當該引數設定為0或者保持預設時,CBO假設全表掃描時最多能連續讀取8個數據塊。從Oracle 11R2開始,DB_FILE_MULTIBLOCK_READ_COUNT的取值演算法如下:
db_file_multiblock_read_count = min(1048576/db_block_size , db_cache_size/
(sessions * db_block_size))
注意 資料庫引數BLOCK_SIZE在設定之後,在資料庫生命週期內不可更改。
當執行SELECT語句時,如果在記憶體裡找不到相應的資料,就會從磁碟讀取進而快取至LRU末端(冷端),這個過程就叫物理讀。當相應資料已在記憶體,就會邏輯讀。我物理讀是磁碟讀,邏輯讀是記憶體讀;記憶體讀的速度遠比磁碟讀來得快。
下面將本人大資料分割槽設計截圖,為大家參考學習。
-
4 # 小小羊羊們
單次肯定是多表連線查詢的效率高,但多次單表查詢的吞吐量高,而且容易最佳化,例如分庫分表,使用快取減少DB訪問次數等等,所以在大資料量高併發場景通常使用多次單表查詢的方式。另外,不管是單表還是多表連線查詢,SQL的執行時間和資料量、併發量都有很大關係,和掃描的資料行數也很有關係。如果一條SQL,平時執行一次要2秒,10個併發時,系統可能一點問題都沒有,1000個併發時,資料庫可能就被拖死了。我們組之前碰到過好幾次這種問題,一張只有幾萬條資料的表,因為忘記加索引,平時執行只有幾百毫秒,高峰期直接飆到幾十秒,DB差點被拖垮。
-
5 # chouc蝙蝠俠
單純從效率來講,join的表不太多時,join效率比較高。但是佔用的主要是資料庫伺服器的資源。資料庫資源又是個瓶頸,不易橫向擴充套件。所以在資料量大的時候,我們會採用單表查詢,把迴圈和匹配等大量工作移到應用伺服器上。應用伺服器容易擴充套件,對併發支援更好。
當資料量大到千萬級以上,就建議儘可能減少join,鼓勵使用單表查詢。查詢最佳化比較容易。這時候使用join的一個大型查詢就可能花很久,對其他查詢造成阻塞,導致服務不可用。
當考慮單表查詢後,就會衍生一系列的策略,比如冷熱資料分離,將熱資料和歷史資料分離,大幅降低資料量級以提高熱資料查詢效能,並可以使用記憶體快取。這樣又促使你考慮引入微服務架構。
總結,資料量小,查詢併發少,那麼使用join的效能是可控的,開發成本低。當數量級上升到千萬級且不斷增加,儘早考慮向單表查詢切換,否則可能有效能下降會導致系統奔潰。而且效能下降不是線性的,會陡降。
回覆列表
先貼倆圖鎮鎮場。
引言對於內連線,使用單個查詢是有意義的,因為你只獲得匹配的行。
對於左連線,多個查詢要好得多。
資料說話看看下面的基準測試:
5個連線的單個查詢
查詢:8.074508秒
結果大小:2268000
一行5個查詢
組合查詢時間:0.00262秒
結果大小:165 (6 + 50 + 7 + 12 + 90)
注意,我們在兩種情況下得到了相同的結果(6 x 50 x 7 x 12 x 90 = 2268000)
總結一下對於冗餘資料,左連線使用更多的記憶體。
如果只執行兩個表的連線,那麼記憶體限制可能沒有那麼糟糕,但通常是三個或更多的表,因此值得進行不同的查詢。
寫在最後用過Laravel嗎?還記得 Eloquent ORM模型嗎?
不知道有沒有注意到,debug所打印出來的多表聯合查詢,
都是拆分為“單個表查詢”,然後使用PHP處理的。
Happy coding :-)