2012-04-09 193 views
1

我有一個擁有450,000條記錄的用戶表。表結構如下:Mysql子查詢優化

UserID Int(11) Primary Key 
    Firstname (50) Varchar 
    Lastname (50) Varchar 

我還需要檢查兩個其他表,以查看UserID是否在這些表中。 (結構有點不同,但表格具有相同的UserID) 我在下面運行此子查詢,並且運行速度非常慢。欣賞第二組的眼睛提供了一個全新的視角,幫助跑快一點的...

SELECT 
`Users`.`Firstname`, 
`Users`.`Lastname`, 
`Users`.`UserID` 
FROM `Users` 
WHERE `Users`.`UserID` IN (SELECT `admin`.`UserID` FROM `admin` WHERE `admin`.`UserID`=`User`.`UserID`) 
AND `Users`.`UserID` IN (SELECT `elite`.`UserID` FROM `elite` WHERE `elite`.`UserID`=`Users`.`UserID`) 
AND `Users`.`Lastname` LIKE '%smith%' 
+0

你有什麼指標在桌子上?爲每個表發佈'SHOW CREATE TABLE ...',併發布'EXPLAIN SELECT ...'輸出。 – 2012-04-09 13:58:38

回答

2

的絕對最重要的事情在MySQL優化查詢的時候是要確保你有適當的指標 。檢查你有什麼索引(使用SHOW INDEX),以及查詢使用什麼索引(使用EXPLAIN SELECT)。一旦表格變大,索引對於良好的性能至關重要。

特別是您應該確保在所有三個表中的UserID列中都有一個索引。如果在你的情況下適合,我還建議添加一個外鍵約束。

不過,如果你已經檢查你有正確的指標,你仍然沒有得到適當的性能,您可以嘗試使用連接,而不是替代的子查詢:

SELECT 
    Users.Firstname, 
    Users.Lastname, 
    Users.UserID 
FROM Users 
JOIN admin USING (UserID) 
JOIN elite USING (UserID) 
WHERE Users.Lastname LIKE '%smith%' 

注意LIKE '%smith%'無法使用索引有效。您應該避免 LIKE表達式,如果可能的話,以通配符開頭。

+1

值得一提的是,你不能在'%smith%'上放置索引。 – DCoder 2012-04-09 14:03:05

+0

@DCoder:已添加。 – 2012-04-09 14:03:51

1

從連接開始;

SELECT 
`Users`.`Firstname`, 
`Users`.`Lastname`, 
`Users`.`UserID` 
FROM `Users` 
INNER JOIN `admin` ON (`Users`.`UserID` = `admin`.`Users`) 
INNER JOIN `elite` ON (`Users`.`UserID` = `elite`.`UserID`) 
WHERE `Users`.`Lastname` LIKE '%smith%' 

然後檢查您的指數。

您應該也不用擔心您的姓氏搜索速度會很慢,因爲它沒有固定在Lastname字符串的開頭或結尾。

2

我猜你應該去內部連接,而不是子查詢...因爲現在你正在從管理表中提取用戶ID,精英表和檢查相同必須在用戶表...所以繼續前進加入並看到不同之處。

+0

同意上述評論 – Madan 2012-04-09 14:01:58