慢mysql子查询

时间:2013-02-18 10:15:52

标签: mysql sql

我正在尝试优化慢速查询,在我的计算机上运行大约需要5分钟,大约在我的服务器上同时运行(有8GB的内存)

SELECT
    buyer_id as bid,
    date_sold as dsold,
    (
        SELECT seller_id
        FROM sale
        WHERE buyer_id = bid
        ORDER BY date_acquired
        LIMIT 1
     ) as sid
from sale
WHERE seller_id = 3585328;

我为此查询创建了一个测试索引。

| sale  |          1 | test                |            1 | buyer_id         | A         |     4900222 |     NULL | NULL   |      | BTREE      |         |
| sale  |          1 | test                |            2 | date_acquired    | A         |    14700667 |     NULL | NULL   |      | BTREE      |         |

当我运行解释时,我得到了

mysql> EXPLAIN SELECT buyer_id as bid,date_sold as dsold, (SELECT seller_id FROM sale WHERE buyer_id = bid ORDER BY date_acquired LIMIT 1) as sid from sale WHERE seller_id = 3585328;
+----+--------------------+-------+------+---------------+------+---------+-------+-------+------------------------------------------+
| id | select_type        | table | type | possible_keys | key  | key_len | ref   | rows  | Extra                                    |
+----+--------------------+-------+------+---------------+------+---------+-------+-------+------------------------------------------+
|  1 | PRIMARY            | sale  | ref  | test          | test | 8       | const | 12466 | Using index                              |
|  2 | DEPENDENT SUBQUERY | sale  | ref  | test          | test | 8       | func  |     3 | Using where; Using index; Using filesort |

我知道子查询可能很慢,但我对如何优化的想法已经不多了。 我不确定它是否重要,但如果我按buyer_id分组,查询运行速度会明显加快。 替换连接感觉很棘手,因为我依赖于子查询中的“限制1”。

2 个答案:

答案 0 :(得分:0)

首先,您的查询对我来说很奇怪。除非我没有得到你想做的事情,否则我没有理解为什么你要做这个子查询,因为你想得到“buyer_id”,但是在哪里买方_id = 3585328;

第二,如果这是一个错字,并且您想要做其他事情的事件,如果你ORDER BY date_acquired,你应该在date_acquired上有一个索引;

答案 1 :(得分:0)

如果您的目的是获取最新的sid;尝试类似的事情:

SELECT
    t1.buyer_id AS bid,
    t1.date_sold AS dsold,
    t1.id AS sid
FROM
    sale AS t1
LEFT OUTER JOIN
    sale AS t2
    ON (t1.buyer_id = t2.buyer_id AND t1.date_acquired < t2.date_acquired)
WHERE t2.date_acquired IS NULL;