0

我有一个具有此架构的表 -

CREATE TABLE `ox_data_summary_device_hourly` (
  `data_summary_device_hourly_id` bigint(20) NOT NULL AUTO_INCREMENT,
  `date_time` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
  ...
   
  ...
  PRIMARY KEY (`data_summary_device_hourly_id`),
  KEY `ox_data_summary_device_daily_date_time` (`date_time`),
  KEY `ox_data_summary_device_daily_ad_country_date_time` (`ad_id`,`date_time`),
  KEY `ox_data_summary_device_daily_zone_id_date_time` (`zone_id`,`date_time`)
) ENGINE=InnoDB AUTO_INCREMENT=3478837682 DEFAULT CHARSET=latin1

因此,在表上设置了以下索引 -

 KEY `ox_data_summary_device_daily_date_time` (`date_time`),
 KEY `ox_data_summary_device_daily_ad_country_date_time` (`ad_id`,`date_time`),
 KEY `ox_data_summary_device_daily_zone_id_date_time` (`zone_id`,`date_time`)

我在这个表上有这个解释查询,带有过滤器date_time-

explain SELECT *

FROM ox_data_summary_device_hourly data_hourly 

WHERE 
data_hourly.date_time >= '2012-09-01 00:00:00' AND data_hourly.date_time < '2012-09-15 13:00:00' 

GROUP BY data_hourly.type ORDER BY data_hourly.type DESC

这是显示ox_data_summary_device_daily_date_time索引未应用的输出 -

在此处输入图像描述

但是,如果我将上述查询中的日期过滤器更改为以下内容 -

data_hourly.date_time >= '2012-09-01 00:00:00' AND data_hourly.date_time < '2012-09-14 13:00:00'

即,如果我查询 9 月 1 日至 14 日而不是 1 日至 15 日,则ox_data_summary_device_daily_date_time索引适用。我进一步检查,如果范围的结束日期在 之后15 sep,则索引不适用。

我很困惑。我检查了表格中是否有日期范围 >= 9 月 15 日的数据。

有任何想法吗?

4

2 回答 2

1

我不确定为什么没有使用索引,但您可以通过添加FORCE INDEX选项来解决这个问题:

SELECT *
FROM ox_data_summary_device_hourly data_hourly 
FORCE INDEX (ox_data_summary_device_daily_date_time)
WHERE 
data_hourly.date_time >= '2012-09-01 00:00:00' AND 
data_hourly.date_time < '2012-09-15 13:00:00' 
GROUP BY data_hourly.type ORDER BY data_hourly.type DESC

此外,您可能会发现使用BETWEEN运算符更容易阅读,甚至可能表现得更好:

SELECT *
FROM ox_data_summary_device_hourly data_hourly 
FORCE INDEX (ox_data_summary_device_daily_date_time)
WHERE 
data_hourly.date_time BETWEEN 
    '2012-09-01 00:00:00' AND 
    '2012-09-15 13:00:00' - INTERVAL 1 SECOND
GROUP BY data_hourly.type ORDER BY data_hourly.type DESC
于 2012-09-17T15:42:01.200 回答
1

对我来说听起来像是优化器 - 它认为查询检查的行太多,无法使索引有用。这就解释了为什么它也适用于较小的范围。

我认为您可以查询较小的日期范围或使用 DATE 而不是 DATETIME。

运行 ANALYZE 或 OPTIMIZE 也可能有所帮助。这是一篇不错的概述文章

祝你好运。

于 2012-09-17T15:48:29.170 回答