2012-09-12 99 views
0

任何人都可以幫助我優化此查詢嗎?它需要15秒。如果我將WHERE子句移動到連接本身,仍然是相同的結果。需要幫助優化加入

SELECT 
`users`.`employeeID` as `username`, 
`users`.`firstName` as `fname`, 
`users`.`lastName` as `lname` 
FROM `enrollment` 
INNER JOIN `users` ON `enrollment`.`employeeID` = `users`.`employeeID` 
WHERE `enrollment`.`number` = [int] 
AND 
`enrollment`.`term` = [int] 
AND 
(
`enrollment`.`status` = 'E' 
OR 
`enrollment`.`status` = 'M' 
) 
ORDER BY  
`users`.`lastName` ASC, 
`users`.`firstName` ASC; 

只要注意到,因爲這:

SELECT 
`users`.`employeeID` as `username`, 
`users`.`firstName` as `fname`, 
`users`.`lastName` as `lname` 
FROM `enrollment` 
INNER JOIN 
`users` ON `enrollment`.`employeeID` = `users`.`employeeID` 
AND 
`enrollment`.`number` = [int] 
AND 
`enrollment`.`term` = [int] 
AND 
(
`enrollment`.`status` = 'E' 
OR 
`enrollment`.`status` = 'M' 
) 
ORDER BY  
`users`.`lastName` ASC, 
`users`.`firstName` ASC; 

這是EXPLAIN結果

id select_type table type possible_keys key key_len ref rows Extra 
1 SIMPLE users ALL PRIMARY NULL NULL NULL 52925 Using filesort 
1 SIMPLE enrollment ref employeeID,number_term employeeID 9 ezlrn.users.employeeID 2 Using where 
+2

請向我們展示您的'EXPLAIN'。 – Kermit

+0

和你現有的索引。 –

+0

我同意njk。在選擇語句前貼上「EXPLAIN」,運行它併發布結果。 SQL看起來很好(我更喜歡第一個),聽起來你可能需要一些索引。 – Tom

回答

0

要回答窮盡我們需要檢查查詢計劃,您獲得發出EXPLAIN SELECT...(your query),索引結構已經到位。

在你有沒有指標,但(也許除了PRIMARY KEY的)的假設,那就是這個問題,讓我們來看看如何掀起的東西(可能進一步improveable):

SELECT 
    `users`.`employeeID` as `username`, 
    `users`.`firstName` as `fname`, 
    `users`.`lastName` as `lname` 
FROM `enrollment` 
    INNER JOIN `users` ON `enrollment`.`employeeID` = `users`.`employeeID` 
WHERE `enrollment`.`number` = [int] 
    AND 
    `enrollment`.`term` = [int] 
    AND 
    (
     `enrollment`.`status` = 'E' 
    OR 
    `enrollment`.`status` = 'M' 
    ) 
    ORDER BY  
     `users`.`lastName` ASC, 
     `users`.`firstName` ASC; 

你有一個JOIN子句之間enrollment.employeeIDusers.employeeID

所以第一對夫婦需要索引的是正確的有:

-- CREATE INDEX enrollment_ndx ON enrollment(employeeID); -- wait on this one 
CREATE INDEX users_ndx ON users(employeeID); 

然後WHERE子句包含一些條件可以有效索引。因此,對於enrollment最終指標是:

CREATE INDEX enrollment_ndx ON enrollment(employeeID, number, term, status); 

嘗試創建的入學率和用戶的索引,然後再試一次(發佈查詢計劃)。

注意:您還可以在查詢中使用語法enrollment.status IN ('M', 'E')來簡化它。

+0

完美,Iserni,謝謝。下降到毫秒查詢:) – KilljoyXP

0

您需要enrollment表中包含(至少一些)number,termstatus的索引。您還需要索引employees(如果它不是主鍵,它應該是)。

CREATE INDEX idx1 ON enrollment (number, term, status); 
CREATE INDEX idx2 ON users (employeeID); // if needed 

這將確保MySQL使用索引來查找在enrollment榜第一,並加入到users表第二。