2014-12-23 73 views
0

我對SQL非常陌生,我試圖找出在涉及多個表時執行選擇的「最佳方式」。不幸的是,我的數據集非常小(因此這個問題相當理論化),所以無論如何,所有內容都會在相同的時間內返回。多表選擇語句的性能

我有如下表(但不那麼抽象數據名):

mysql> describe tblA 
+----------------+-------------+------+-----+---------+----------------+ 
| Field   | Type  | Null | Key | Default | Extra   | 
+----------------+-------------+------+-----+---------+----------------+ 
| ID    | bigint(20) | NO | PRI | NULL | auto_increment | 
| A_data   | varchar(20) | YES |  | null |    | 
| B_ID   | bigint(20) | NO | MUL | NULL |    | 
+----------------+-------------+------+-----+---------+----------------+ 
mysql> describe tblB 
+----------------+-------------+------+-----+---------+----------------+ 
| Field   | Type  | Null | Key | Default | Extra   | 
+----------------+-------------+------+-----+---------+----------------+ 
| ID    | bigint(20) | NO | PRI | NULL | auto_increment | 
| B_data   | varchar(20) | YES |  | null |    | 
| C_ID   | bigint(20) | NO | MUL | NULL |    | 
+----------------+-------------+------+-----+---------+----------------+ 
mysql> describe tblC 
+----------------+-------------+------+-----+---------+----------------+ 
| Field   | Type  | Null | Key | Default | Extra   | 
+----------------+-------------+------+-----+---------+----------------+ 
| ID    | bigint(20) | NO | PRI | NULL | auto_increment | 
| C_data   | varchar(20) | YES |  | null |    | 
+----------------+-------------+------+-----+---------+----------------+ 

似乎有三種方式,我可以安排一個查詢來獲取A_data給出一個特定的值C_DATA:

SELECT A_data FROM tblA,tblB,tblC 
    WHERE (tblC.C_data=searchKey AND tblB.C_ID=tblC.ID AND tblA.B_ID=tblB.ID) 

SELECT A_data FROM tblA 
    INNER JOIN tblB ON tblA.tblB_ID=tblB.ID 
    INNER JOIN tblC ON tblB.tblC_ID=tblC.ID 
    WHERE tblC.C_data=searchKey 

SELECT A_data FROM tblA 
    WHERE tblB_ID IN (
    SELECT ID FROM tblB WHERE tblC_ID IN (
     SELECT ID FROM tblC WHERE tblC_data=searchKey 
    ) 
) 

我很好奇這些技術的相對衍生和優點(如果有的話)。例如,加入三張表只是爲了進行搜索,似乎打敗了將它們保存在單獨表格中的觀點,但相反,我不確定嵌套選擇的智慧。我也不清楚第一個案例背景中發生了什麼。

+1

版本A是使用舊標準的連接語法。完全有效並且應該導致與使用更新標準的選項B相同的性能。選項C是迄今爲止表現最差的。系統必須首先實現兩個子選擇以獲得期望的結果。此外,如果您需要來自tblB或tblC的信息,則選項C將不起作用。這不是一個「JOIN」 – xQbert

回答

1

使用第二種形式。這是三種中最常見也是最可讀的。

  • MySQL很可能在內部使第一種形式與第二種形式相同。檢查執行計劃。不管怎麼樣,這並不容易,因爲3個表格之間的關係並不明顯。
  • 第三種形式更難以優化,特別是涉及更多表格時。躲開它。
+0

謝謝!我是否正確地假設使用子表的原因既是存儲要求又是性能?如果我有效地加入我的系統中的每個表格(出於某種原因),我是否正在有效地構建一個龐大的表格,從而擊敗了擁有多個表格的問題? – aqua

+1

當涉及到子表的使用時,它非常符合個人編碼風格。但是當你嵌入太深時,閱讀和優化就會變得更加困難(編碼與開發人員一樣需要對其進行維護)。將數據庫中的每個表加在一起是理論上合理的原因 - 這是關係數據的定義。你將數據分解成小的相關部分,以便稍後將所有數據整合回去。 –

0

警告:不是我的專業領域,這不是您的問題的直接答案。但是,查看MySQL優化器跟蹤選項對您來說可能很有用,因爲它應該闡明查詢優化器對您的SQL執行什麼操作以及如何執行它。 相關鏈接:

http://dev.mysql.com/doc/internals/en/optimizer-tracing.html - (Oracle官方文檔) http://jorgenloland.blogspot.com/2011/10/optimizer-tracing-query-execution-plan.html - (使用情況和輸出是什麼意思,筆記從優化發展)