MySQL SELECT JOIN WHERE ORDER BY performance

时间:2017-08-18 12:07:31

标签: php mysql

我有两张桌子正在成长,而且这些桌子总是表现得很好,不再那么快了。

我有两张桌子:

# Accounts table
CREATE TABLE `account` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `firstname` varchar(50) DEFAULT NULL,
  `lastname` varchar(50) DEFAULT NULL,
  `email` varchar(100) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `email` (`email`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

# Orders table
CREATE TABLE `order` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `account_id` int(11) DEFAULT NULL,
  `datetime` datetime DEFAULT NULL,
  `ip` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `account_id` (`account_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

请参阅SQLFiddle for full example数据。

有问题的查询

SELECT 
    o.id,
    a.email
FROM `order` o
JOIN account a ON o.account_id = a.id
WHERE a.email LIKE '%@hotmail.com%'
ORDER BY o.id DESC
LIMIT 2

只需几条记录即可快速运行此查询。但是使用EXPLAIN功能会显示它会搜索帐户表中的所有记录,而不是2的有限集合。 enter image description here

ORDER BY o.id DESC会导致较大的表格出现问题。我怎样才能以最好的方式解决这个问题?

  1. 在两个查询中拆分查询。首先获取所有匹配的帐户,然后使用order WHERE o.account_id IN (1, 3, 5) ORDER BY o.id DESC进行第二次查询。
  2. 使用子查询(不知道如何)。
  3. 其他选择......
  4. 我打开了有关如何在更大的数据集中处理此类查询的建议。

    注意:我知道这个问题被多次询问,但这些问题没有我可以使用的答案。

2 个答案:

答案 0 :(得分:1)

这个怎么样:

SELECT 
o.id,
a.email
FROM `order` o
JOIN (SELECT id, email 
FROM account 
WHERE email LIKE '%@hotmail.com%') a ON o.account_id = a.id
ORDER BY o.id DESC;

答案 1 :(得分:0)

我认为你可能会“欺骗”MySQL以这样的方式推迟查找(未经测试):

SELECT x.id
     , x.email
  FROM    
     ( SELECT o.id
            , a.email
         FROM `order` o
         JOIN account a 
           ON o.account_id = a.id
        WHERE a.email LIKE '%@hotmail.com%'
        ORDER 
           BY o.id DESC
        LIMIT 2
     ) x
  JOIN `order` y
    ON y.id = x.id
 ORDER 
    BY y.id;