『壹』 對資料庫進行多表聯合查詢,是不是有很大的性能影響
必須的。影響比較大,10萬不到的兩個表 left outer join 如果右表有null 還要group 之類 沒2 30秒 查不出來
常用的話, 建議做新表 外鍵約束 或者過程存儲
『貳』 資料庫-聯表查詢
SQL使用(一)——聯合查詢
1.聯合查詢分類
內連接(inner Join 或 Join)
外連接(outer Join)
左外連接(left outer Join 或 left Join)
右外連接(right outer Join 或 right Join)
全外連接(full outer Join 或 full Join)
交叉連接 (cross Join)
結果集鏈接 (union 和 union all)
2.聯合查詢介紹
相關數據表如下:
A表
B表
C表
2.1內連接(Inner Join)
內連接:僅顯示兩個表中匹配行,即兩表中都有才顯示。
SQL如下:
SELECT A.id AS AID, A.content AS AContent, B.id AS BID, B.content AS BContent FROM A INNERJOIN B ON (A.id = B.id);
1
2
3
4
5
6
7
8
查詢結果:
由查詢結果可以看出,內連接根據連接條件(A.id=B.id)查詢出了A、B兩表中都存在的數據信息。2個表的聯合查詢結果如此,那麼3個表甚至更多表聯合查詢的結果呢?
A、B、C三表聯合內查詢SQL
SELECTA.idASAID, A.contentASAContent, B.idASBID, B.contentASBContent, C.idASCID, C.(A.id = B.id)INNERJOINCON(A.id = C.id)
1
2
3
4
5
6
7
8
9
10
11
查詢結果:
啊?怎麼多了一行數據?不用驚訝,其實C表中有2個id為1的記錄,然而我們怎麼理解得到的查詢結果呢?
可以把A、B兩表的查詢結果作為T表(中間結果表),然後T表內連接C表,連接條件為T.A.id=C.id。
簡單來說n(n>=2)都可以看做兩張表的聯合查詢,後面的小節將只介紹兩個表的聯合查詢。
2.2外連接(Outer Join)
2.2.1左外連接(Left outer Join)
左外連接:左表有就顯示,不論右表。
SQL:
SELECTA.idASAID, A.contentASAContent, B.idASBID, B.(A.id = B.id);
1
2
3
4
5
6
7
8
查詢結果:
左連接並不是把B表左連接到A表上,而是把A表作為基準表。由查詢結果可以看出,A、B兩表左連接,只要A中有結果,無論B表中有無結果,都會被查詢出來。
2.2.2右外連接(Right outer Join)
右外連接:右表有就顯示,不論左表。
SQL:
SELECTA.idASAID, A.contentASAContent, B.idASBID, B.(A.id = B.id);
1
2
3
4
5
6
7
8
9
查詢結果:
右連接和左連接類似,只是把B表(連接的表)作為基準表。由查詢結果可以看出,無論A表是否存在其他數據,只要B表數據存在就會被查詢出來。
2.2.3全外連接(Full outer Join)
全外連接:左表/右表,有一個有就顯示。
SQL:
SELECTA.idASAID, A.contentASAContent, B.idASBID, B.(A.id = B.id);
1
2
3
4
5
6
7
8
9
查詢結果:
全外連接查詢就字面意思也不難看出是查詢出兩表(A、B)中的所有記錄信息。
註:MySQL中不支持全外連接(但是可以union來實現,後面會介紹)。
2.2交叉連接(Cross Join)
SQL:
SELECTA.idASAID, A.contentASAContent, B.idASBID, B.;
1
2
3
4
5
6
7
8
9
查詢結果:
由結果可以看出,交叉連接是對A、B量表進行笛卡爾積的結果查詢出來。即A的每條記錄都有和B中所有記錄相對應的信息。
2.3 SQL Union
SQL Union用於將多個select結果集進行合並。值得注意的是,UNION 內部的 SELECT 語句必須擁有相同數量的列。列也必須擁有相似的數據類型。同時,每條 SELECT 語句中的列的順序必須相同。
SQL:
SELECT*FROMAUNIONSELECT*fromB;
1
查詢結果:
Union是把2個Select結果集進行合並,由查詢結果也不難看出,A、B兩表的結果數據進行了合並,並且都被查詢出來了。
如果2個Select結果集中存在相同的結果,用Union則會把相同的記錄進行合並,查詢結果中僅僅會顯示一條。那麼如果想都顯示出來,把Union換成Union All 即可。
Union實現Full outer Join:
1.首先獲取A、B表中id的不同組合。
SQL:
CREATEVIEWvasSELECTA.idfromAUNIONSELECTB.idfromB;
1
視圖內存如下:
2.以視圖V為基本表,Left Join A、B表即可。
SQL:
SELECTA.id, A.content, B.id, B.contentFROMvLEFTJOINAON(A.id = v.id)LEFTJOINBON(B.id = v.id);
1
2
3
4
5
6
7
8
9
查詢結果如下:
『叄』 mysql索引建多了有什麼壞處
你現在種方法效率其實是差不多的,都非常低,極端低,最低
一、如果不改進效率,只簡化程序,我有建議你對新聞類別進行二進制編碼,仍然使用features一個欄位來表示,欄位為整數類型,使用最低開始的四個二進制位是否為1來表示是否為圖片新聞、頭條新聞、首頁新聞、重要新聞,例如7(二進制的0111)表示具有頭條、首頁、重要三個屬性。查詢的時候使用位運算&來實現,圖片新聞、頭條新聞、首頁新聞、重要新聞的權重分別是8、4、2、1,這時候假若調用三條是圖片新聞的新聞時,直接可以用sql語句:
select * from news where features & 8=8 order by news_id desc limit 0,3;
假若調用三條是圖片新聞、並且重要新聞時,直接可以用sql語句:
select * from news where features & 9=9 order by news_id desc limit 0,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末端(冷端),這個過程就叫物理讀。當相應數據已在內存,就會邏輯讀。我物理讀是磁碟讀,邏輯讀是內存讀;內存讀的速度遠比磁碟讀來得快。
下面將本人大數據分區設計截圖,為大家參考學習。
先貼倆圖鎮鎮場。
引言
對於內連接,使用單個查詢是有意義的,因為你只獲得匹配的行。
對於左連接,多個查詢要好得多。
看看下面的基準測試:
5個連接的單個查詢
一行5個查詢
注意,我們在兩種情況下得到了 相同的結果 (6 x 50 x 7 x 12 x 90 = 2268000)
對於冗餘數據,左連接使用更多的內存。
如果只執行兩個表的連接,那麼內存限制可能沒有那麼糟糕,但通常是三個或更多的表,因此值得進行不同的查詢。
用過Laravel嗎?還記得 Eloquent ORM模型嗎?
不知道有沒有注意到,debug所列印出來的多表聯合查詢,
都是拆分為「單個表查詢」,然後使用PHP處理的。
Happy coding :-)
是做表連接查詢還是做分解查詢要具體情況具體分析。
如果資料庫的結構合理,索引設計得當,表連接的效率要高於分解查詢。比如,在有外鍵的時候,資料庫可以為外鍵建表並建立索引從而提升多個表連接查詢的效率。另外,多表連接查詢不需要把數據傳輸到應用程序中,直接在資料庫端執行,這在很大程度上提升了效率。
但是多表連接也有一些缺點。多表連接對表結構的依存度很高,只要表結構出現變更就會同時對資料庫檢索和應用處理兩個部分產生較大影響。另外,多表連接的兼容性不好,資料庫不同SQL文也多少有些差異。而且採用分散資料庫的時候,實現多表連接即麻煩又沒有什麼好處。因此,一些大型系統或者是支持多種類資料庫的系統一般不會使用多表連接,而傾向於採用分解查詢。
這個得看情況,一般數據不大的情況下多表連接查詢和多次單表查詢的效率差不多。如果數據量足夠大,那肯定是多次單表查詢的效率更高。在很多大的公司裡面,都會禁用多表連接查詢,原因就是一旦數據量足夠大的時候多表連接查詢效率會很慢,而且不利於分庫分表的查詢優化。那麼看一下下面這個例子。
兩種查詢方式的比較我這里有一個資料庫,我們拿裡面的客戶表和地區表做兩種查詢的對比。用戶表數據是31萬條,地區表3511條。
1. 使用連表查詢成都市的客戶總數
2.使用多次單表查詢客戶總數
可以看到,查詢出來的結果都是一樣,但是第一種的連表查詢用了0.67秒中,而第二種多次單表查詢一共用時0.14秒。這個對比已經是很明顯了吧。
雖然這只是一個很簡單的例子,但是對比結果是非常明顯的。在實際應用中可能會更復雜、數據更多,如果還使用連表查詢時非常慢的,而且還消耗伺服器資源。
所以現在在很多大了公司明確要求禁止使用join查詢,比如阿里、騰訊就明確規定禁用三表以上的join查詢。
總結一下,單表查詢的優點1. 多次單表查詢,讓緩存的效率更高。
許多應用程序可以方便地緩存單表查詢對應的結果對象。另外對於MySQL的查詢緩存來說,如果關聯中的某個表發生了變化,那麼就無法使用查詢緩存了,而拆分後,如果某個表很少改變,那麼基於該表的查詢就可以重復利用查詢緩存結果了。
2. 將查詢分解後,執行單個查詢可以減少鎖的競爭。
3. 在應用層做關聯,更容易對資料庫進行拆分,更容易做到高性能和可擴展。
4. 查詢本身效率也可能會有所提升。
5. 可以減少冗餘記錄的查詢。
6. 在應用中實現了哈希關聯,而不是使用MySQL的嵌套環關聯,某些場景哈希關聯的效率更高很多。
7. 單表查詢有利於後期數據量大了分庫分表,如果聯合查詢的話,一旦分庫,原來的sql都需要改動。
8. 很多大公司明確規定禁用join,因為數據量大的時候查詢確實很慢
所以在數據量不大的情況下,兩種方式的查詢都沒什麼明顯的差別,使用多表連接查詢更方便。但是在數據量足夠大幾十萬、幾百萬甚至上億的數據,或者在一些高並發、高性能的應用中,一般建議使用單表查詢。
如果覺得笨貓的回答對你有用,點個關注,非常感謝。
做java的,在orm框架下,分解查詢是最符合面向對象操作的,挺支持分解查詢的(拙見)
先說結論:不一定。
多表查詢效率低的時候,可以考慮拆解sql成多個小的sql,至於效率是否一定會提高,這個還不一定,具體問題具體問題。當多表查詢效率低的時候,拆解成單個小sql,這只是一個可能的思路,起不起作用,不一定。
sql是一個很復雜的東西,sql引擎會分析執行計劃,並可能按照他認為最優的執行計劃執行sql,但他認為的也不一定是正確的。不同的sql執行計劃不一樣,所以很難斷定sql拆解或者合並的效率。
說了這么多,那到底是多表聯合查詢還是拆解呢?有沒有一個原則? 有!如果你確定你的單個sql的執行效率比較快,當然可以寫多個單個sql。當然了,具備這個能力需要你對資料庫足夠了解,比如什麼時候走索引,什麼時候nested loop等等。如果你現在的多表聯合查詢比較慢,你需要找出來慢的原因,並分析拆解後的sql的執行計劃,看是否避免了多表聯合查詢的效率問題。
總之吧。這個問題,只能給你一個大體的思路,因為牽扯到很多基礎問題,我覺得最起碼sql執行計劃應該需要了解,一個sql可能的執行計劃有幾十中,復雜sql的執行計劃又是這幾十種的組合。哪種效率低,哪種效率高應該有個大體了解。
多表查詢可以很快,也可以很慢。主要看執行計劃。
單次肯定是多表連接查詢的效率高,但多次單表查詢的吞吐量高,而且容易優化,例如分庫分表,使用緩存減少DB訪問次數等等,所以在大數據量高並發場景通常使用多次單表查詢的方式。另外,不管是單表還是多表連接查詢,SQL的執行時間和數據量、並發量都有很大關系,和掃描的數據行數也很有關系。如果一條SQL,平時執行一次要2秒,10個並發時,系統可能一點問題都沒有,1000個並發時,資料庫可能就被拖死了。我們組之前碰到過好幾次這種問題,一張只有幾萬條數據的表,因為忘記加索引,平時執行只有幾百毫秒,高峰期直接飆到幾十秒,DB差點被拖垮。
單純從效率來講,join的表不太多時,join效率比較高。但是佔用的主要是資料庫伺服器的資源。資料庫資源又是個瓶頸,不易橫向擴展。所以在數據量大的時候,我們會採用單表查詢,把循環和匹配等大量工作移到應用伺服器上。應用伺服器容易擴展,對並發支持更好。
當數據量大到千萬級以上,就建議盡可能減少join,鼓勵使用單表查詢。查詢優化比較容易。這時候使用join的一個大型查詢就可能花很久,對其他查詢造成阻塞,導致服務不可用。
當考慮單表查詢後,就會衍生一系列的策略,比如冷熱數據分離,將熱數據和 歷史 數據分離,大幅降低數據量級以提高熱數據查詢性能,並可以使用內存緩存。這樣又促使你考慮引入微服務架構。
總結,數據量小,查詢並發少,那麼使用join的性能是可控的,開發成本低。當數量級上升到千萬級且不斷增加,盡早考慮向單表查詢切換,否則可能有性能下降會導致系統奔潰。而且性能下降不是線性的,會陡降。
『伍』 影響資料庫性能的主要因素有哪些
以MySQL為例:
1、sql查詢速度
2、網卡流量
3、伺服器硬體
4、磁碟IO
以上因素並不是時時刻刻都會影響資料庫性能,而就像木桶效應一樣。如果其中一個因素嚴重影響性能,那麼整個資料庫性能就會嚴重受阻。另外,這些影響因素都是相對的。
例如:當數據量並沒有達到百萬千萬這樣的級別,那麼sql查詢速度也許就不是個重要因素,換句話說,你的sql語句效率適當低下可能並不影響整個效率多少,反之,這種情況,無論如何怎麼優化sql語句,可能都沒有太明顯的效果。
1、SQL查詢速度
風險:效率低下的SQL
2、網卡流量
風險:網卡IO被占滿(100Mb/8=100MB)
方案:
①減少從伺服器的數量。從伺服器都要從主伺服器上復制日誌,所以,從伺服器越多,網路流量越大。
②進行分級緩存。前方大量緩存突然失效會對資料庫造成嚴重的沖擊。
③避免使用「select * 」進行查詢
④分離業務網路和伺服器網路
3、磁碟IO
風險:磁碟IO性能突然下降。
方案:使用更好的磁碟設備解決。