如何改善我的查询?

时间:2012-01-20 19:17:45

标签: sql performance query-optimization

我需要计算超过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 JOINLEFT JOIN ON a.published_date >= m.latest_activity_date但结果相同。它还显示所有行都被读取而没有使用索引(但是它将IDX_8484BF65454ADE21显示为“可能的索引”)

有什么想法吗?

1 个答案:

答案 0 :(得分:0)

除了表之间没有连接条件外,它基本上会对它们进行笛卡尔连接(这是一团糟)。

另外,我会先根据您的“固定”值的标准调整您的索引,然后根据您的日期范围...来澄清......您的

WHERE
       m.Status = "enabled" 
   AND m.Type = "foo"
   AND ... other date specific...

索引(状态,类型,日期......)

最后,为什么这么长的状态和类型的字段...这些类型的字段在正常条件下会更加缩写,而在MOST,我会将这样的列作为15-20个字符。每个字段最多包含255个字符的索引页面也会大大缩短查询时间。