我有下一个查询:
SELECT JL.j_id, COUNT(*) as total
FROM j_log JL
WHERE JL.log_time > '20120205164008'
AND JL.j_id IN (
SELECT j_id
FROM j
WHERE checked = '1'
AND expires >= '20120207164008'
) GROUP BY JL.j_id ORDER BY total DESC LIMIT 3
j表中有大字结构100个字段和248986行。
下一个KEY存在于其中
PRIMARY KEY (`j_id`),
KEY `expires` (`expires`),
KEY `checked` (`checked`),
KEY `checked_2` (`checked`,`expires`)
j_log表有大约63000000条记录和下一个结构
CREATE TABLE `j_log` (
`j_id` int(11) NOT NULL DEFAULT '0',
`member_id` int(11) DEFAULT NULL,
`ip` int(10) unsigned NOT NULL DEFAULT '0',
`log_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
KEY `j_id` (`j_id`),
KEY `log_time` (`log_time`),
KEY `ip` (`ip`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
因此,所考虑的查询想要获得大多数访问过的j_id实例的前三名
这是计划
+----+--------------------+-------+-----------------+-----------------------------------+---------+---------+------+----------+----------+----------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+--------------------+-------+-----------------+-----------------------------------+---------+---------+------+----------+----------+----------------------------------------------+
| 1 | PRIMARY | JL | index | log_time | j_id | 4 | NULL | 63914602 | 0.36 | Using where; Using temporary; Using filesort |
| 2 | DEPENDENT SUBQUERY | j | unique_subquery | PRIMARY,expires,checked,checked_2 | PRIMARY | 4 | func | 1 | 100.00 | Using where |
+----+--------------------+-------+-----------------+-----------------------------------+---------+---------+------+----------+----------+----------------------------------------------+
有时可能需要15个!!!分钟。
有什么方法可以加快速度吗?
答案 0 :(得分:0)
SELECT JL.j_id, COUNT(*) as total
FROM j_log JL
INNER JOIN j
ON JL.j_id = j.j_id
AND j.checked = '1'
AND j.expires >= '20120207164008'
WHERE JL.log_time > '20120205164008'
GROUP BY JL.j_id
ORDER BY total
DESC LIMIT 3
这会更快吗?
答案 1 :(得分:0)
checked
是一个字符串? ('1'而不是1)jl.log_time
和j.expires
(>
vs >=
)这个查询怎么样
SELECT j.j_id, COUNT(jl.j_id) as total
FROM j
LEFT JOIN j_log jl ON (jl.j_id = j.j_id AND jl.checked = '1' AND jl.log_time > '20120205164008')
WHERE j.expires >= '20120207164008'
GROUP BY j.j_id
ORDER BY total DESC
LIMIT 3
确保j_id
为两个表的PRIMARY KEY
,并在j.expires和jl.checked以及jl.logtime上放置索引。
还要确保优化字段checked
。我不确定可能的值是什么,但我认为它是一个布尔字段。所以请改为使用field_type BIT
或使用ENUM
修改强>
此外,您应该将字段j.expires
和jl.log_time
转换为更好的字段。我认为它现在只是varchar
,查看您使用的当前值:20120205164008.将其转换为DATETIME
字段(但不要只是转换表,因为您将丢失数据)。