2012-06-29 86 views
1

我想知道內部連接在mysql中的工作原理。INNER JOIN執行/評估順序

如果我不

SELECT * FROM A a 
INNER JOIN B b ON a.row = b.row 
INNER JOIN C c ON c.row2 = b.row2 
WHERE name='Paul'; 

它做的第一連接,然後挑選那些地方名=保羅?因爲當我這樣做的時候,這是超級減速慢。

是有辦法沿線做一些事情:

SELECT * FROM (A a WHERE name='paul') 
INNER JOIN B b ON a.row = b.row 
INNER JOIN C c ON c.row2 = b.row2] 

當我嘗試這樣的說法,我只是得到一個錯誤。

或者,更好的是隻有3個單獨的查詢,一個用於A,B和C?例如:

string query1 = "SELECT * FROM A WHERE name = 'paul'"; 
//send query, get data reader 
string query2 = "SELECT * FROM b WHERE b = " + query1.b; 
//send query, get data reader 
string query3 = "SELECT * FROM C WHERE c = " + query1.c; 
//send query, get data reader 

顯然這只是僞代碼,但我認爲它說明了一點。

哪種方式更快/推薦?

編輯 表結構:

**tblTimesheet** 
int timesheetID (primary key) 
datetime date 
varchar username 
int projectID 
string description 
float hours 

**tblProjects** 
int projectID (primary key) 
string project name 
int clientID 

**tblClients** 
int clientID 
string clientName 

The join that I want is: 

select * from tblTimesheet time 
INNER JOIN tblProject proj on time.projectID = proj.projectID 
INNER JOIN tblClient client on proj.clientID = client.clientID 
WHERE username = 'paul'; 

類似的東西

+0

第一個查詢看起來很好的教程;你的行號是否被索引? –

+0

這個問題也在這個問題上觸及 - http://stackoverflow.com/questions/228424/in-what-order-are-mysql-joins-evaluated – dash

回答

2

你可能缺少關鍵表上的索引;您可以使用MySql EXPLAIN關鍵字來幫助查找查詢速度緩慢的位置。

要回答您問題的另一部分;

is there a way to do something along the lines: 

SELECT * FROM (A a WHERE name='paul') 
INNER JOIN B b ON a.row = b.row 
INNER JOIN C c ON c.row2 = b.row2] 

可以使用SubQuery;

SELECT * 
FROM (SELECT * FROM tblTimesheet WHERE username = 'Paul') AS time 
INNER JOIN tblProject proj on time.projectID = proj.projectID 
INNER JOIN tblClient client on proj.clientID = client.clientID 

此查詢實際做的是試圖預先過濾JOIN將操作的字段。與其將所有字段連接在一起,然後將其過濾掉,它只會嘗試從名爲'Paul'的tblTimesheet中加入字段。

但是,查詢優化器應該已經這樣做了,因此該查詢應該與原始查詢類似。

與索引更多的幫助,瞭解這將大大幫助您在數據庫開發,開始通過看像this one.

2

這是飛馳不可能聯接將慢於三個數據庫命中。如果MySQL的查詢優化器完全勝任,重新排序子句應該不會產生任何影響。 WHERE/ON子句中的列是否已編入索引?

+0

雅,我不認爲這種方式會更快...只是想我會問。 你是什麼意思索引? – Toadums

+0

@Toadums如果一列被編入索引,這意味着在向其中插入一個值時要花費一些磁盤空間/內存和CPU時間,使檢索速度更快。您應該爲要用於查找行的每一列添加一個索引。我還建議通過介紹性數據庫系統教科書進行分頁。 – millimoose

2

我想你會發現查詢優化器在大多數情況下會給你最好的查詢。您需要查看執行計劃以瞭解查詢速度緩慢的原因 - 我的猜測是缺少索引。

當MySql在這些表中查找時,通常會以最佳方式獲得最佳速度 - 如您所示的簡單連接不會混淆查詢優化器,但缺少索引可能會導致數據庫引擎掃描表而不是查找值(即它需要逐行掃描表以匹配您指定的標準)

索引確保引擎不需要向下搜索到葉級頁級並且通常會加快查詢速度

這裏的表結構是什麼或者這是否都是假設?

SQL的一般經驗法則是 - 試試看看!

+0

我更新了我的問題,顯示了表結構。大家都說過使用索引,我怎麼用我的例子來做這件事?謝謝! – Toadums

+1

ALTER TABLE TableName ADD INDEX IndexName(FieldName) – Jeff

+0

@Jeff好,好像容易!那麼我想要一個用戶名索引呢? (我假設主鍵比索引更快) – Toadums

1

用你的第一個查詢,MySQL查詢優化器應該選擇最快的戰略

,如果你希望它是更快,確保上有name列的索引