我有一个查询,查看用户(m_id)查看过的所有课程(o_id)、他们给它的最后评分(第一个子查询)和最后一次评分(第二个子查询)
该查询在生产中很快,但最近在我的开发机器上它停止了,我今天发现它花了1800 秒。
SELECT o_id i , UNIX_TIMESTAMP(mo_access_date) a, mo_complete c, mo_quizscore q,
(
SELECT mlr_rating
FROM member_lesson_rating
WHERE m_id=mo.m_id&&o_id=mo.o_id
ORDER BY mlr_id DESC
LIMIT 1
) r,
(
SELECT if(mlr_rating > 0, UNIX_TIMESTAMP(mlr_created),null) x
FROM member_lesson_rating
WHERE m_id=mo.m_id&&o_id=mo.o_id
ORDER BY mlr_id DESC
LIMIT 1
) u
FROM member_object_tbl mo
WHERE m_id=64206
和描述(
+----+--------------------+----------------------+-------+------------------+----------+---------+-------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+--------------------+----------------------+-------+------------------+----------+---------+-------+------+-------------+
| 1 | PRIMARY | mo | ref | opt_cols,m_id | opt_cols | 4 | const | 99 | |
| 3 | DEPENDENT SUBQUERY | member_lesson_rating | index | m_id,m_id_2,o_id | PRIMARY | 4 | NULL | 1 | Using where |
| 2 | DEPENDENT SUBQUERY | member_lesson_rating | index | m_id,m_id_2,o_id | PRIMARY | 4 | NULL | 1 | Using where |
+----+--------------------+----------------------+-------+------------------+----------+---------+-------+------+-------------+
分析查询表明每个子查询在我的测试中占用一秒钟......(即1 * 99)
和创建表
CREATE TABLE `member_lesson_rating` (
`mlr_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`m_id` int(10) unsigned NOT NULL,
`o_id` int(10) unsigned NOT NULL,
`mlr_created` datetime NOT NULL,
`mlr_rating` tinyint(4) NOT NULL,
PRIMARY KEY (`mlr_id`),
KEY `m_id` (`m_id`,`o_id`),
KEY `m_id_2` (`m_id`),
KEY `o_id` (`o_id`)
) ENGINE=MyISAM AUTO_INCREMENT=2882202 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
更新:不会导致任何问题的新查询
SELECT
mo.o_id i ,
UNIX_TIMESTAMP(mo_access_date) a,
mo_complete c,
mo_quizscore q,
if(mlr_rating > 0, UNIX_TIMESTAMP(mlr_created),null) u,
mlr_rating r
FROM
(SELECT * FROM member_object_tbl WHERE m_id=?) mo
LEFT JOIN
(
SELECT *
FROM (
SELECT *
FROM member_lesson_rating
WHERE m_id=?
ORDER BY mlr_id DESC
) mlr2
GROUP BY o_id
) mlr
ON mo.o_id=mlr.o_id