1

我有一个包含 450,000 条记录的用户表。表结构如下:

  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%'
4

3 回答 3

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 表达式。

于 2012-04-09T14:00:13.000 回答
2

我想您应该使用内部联接而不是子查询...因为现在您正在从 admin 表、elite 表中获取用户 id 并检查是否必须在用户表中...所以继续加入并查看区别。

于 2012-04-09T14:01:11.883 回答
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字符串的开头或结尾。

于 2012-04-09T14:00:17.483 回答