我需要计算超过150'000行的数字(增长),但我的查询速度很慢。
以下是CREATE TABLE
:
CREATE TABLE `device` (
`id` int(11) NOT NULL auto_increment,
`registration_id` varchar(255) NOT NULL,
`creation_date` datetime NOT NULL,
`latest_activity_date` datetime NOT NULL,
`status` varchar(255) NOT NULL,
`type` varchar(255) NOT NULL,
PRIMARY KEY (`id`),
KEY `IDX_8484BF65454ADE21` (`latest_activity_date`,`status`,`type`)
) ENGINE=InnoDB AUTO_INCREMENT=160969 DEFAULT CHARSET=utf8;
CREATE TABLE `article` (
`id` int(11) NOT NULL auto_increment,
`summary` longtext NOT NULL,
`creation_date` datetime NOT NULL,
`published_date` datetime default NULL,
`updated_date` datetime default NULL,
PRIMARY KEY (`id`),
KEY `IDX_A5051EECA76ED395` (`user_id`),
KEY `IDX_A5051EEC7B00651C9E0806AB` (`published_date`)
) ENGINE=InnoDB AUTO_INCREMENT=20216 DEFAULT CHARSET=utf8;
我需要根据每个设备的最新活动日期获取已发布文章的数量。
所以我这样做:
SELECT m.registration_id, COUNT(a.id)
FROM device m, article a
WHERE (
m.latest_activity_date < CURRENT_TIMESTAMP AND
a.published_date >= m.latest_activity_date AND
m.status = 'enabled' AND
a.published_date <= CURRENT_TIMESTAMP AND (
m.registration_id <> '' OR
m.registration_id IS NOT NULL
)
) AND m.type = 'foo'
GROUP BY m.registration_id
HAVING COUNT(a.id) > 0
但是这个查询有点慢(约有3000篇文章和150000台设备超过50秒)
我尝试EXPLAIN
,但它没有提供任何线索。我也尝试了一个显式连接(使用INNER JOIN
和LEFT JOIN ON a.published_date >= m.latest_activity_date
但结果相同。它还显示所有行都被读取而没有使用索引(但是它将IDX_8484BF65454ADE21显示为“可能的索引”)
有什么想法吗?
答案 0 :(得分:0)
除了表之间没有连接条件外,它基本上会对它们进行笛卡尔连接(这是一团糟)。
另外,我会先根据您的“固定”值的标准调整您的索引,然后根据您的日期范围...来澄清......您的
WHERE
m.Status = "enabled"
AND m.Type = "foo"
AND ... other date specific...
索引(状态,类型,日期......)
最后,为什么这么长的状态和类型的字段...这些类型的字段在正常条件下会更加缩写,而在MOST,我会将这样的列作为15-20个字符。每个字段最多包含255个字符的索引页面也会大大缩短查询时间。