2012-04-09 151 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