考虑以下查询:

SELECT * FROM Transactions
WHERE day(Stamp - interval 3 hour) = 1;

邮票交易 表是时间戳,上面有索引。我该如何更改此查询以避免全表扫描? (也就是说,使用 邮票 外面 天() 功能)

谢谢!

有帮助吗?

解决方案

这就是我这样做的方式:

添加一些额外的字段:根据您期望的流量,一年,月,每天甚至小时,分钟。然后构建一个触发器以填充额外的字段,也许会提前减去3小时的间隔。最后在额外的字段上构建一些索引。

其他提示

如果目标只是为了避免全表扫描,并且您有一个主键(例如,命名为PK),请考虑添加覆盖索引

ALTER TABLE Transactions ADD INDEX cover_1 (PK, Stamp)

然后

SELECT * FROM Transactions WHERE PK IN (SELECT PK FROM Transactions
WHERE day(Stamp - interval 3 hour) = 1
 )

此查询不应使用完整的表扫描(但是,如果表格中的行很小或出于任何其他统计原因,那么优化器可能会决定使用完整的扫描:))

更好的方法可能是使用临时表而不是子查询。

您通常可以重写该功能,以便您拥有看起来像 WHERE Stamp=XXXX XXXX是一些表达。您可以在每个月之间创建一系列语句, WHERE Stamp BETWEEN timestamp('2010-01-01 00:00:00') AND timestamp ('2010-01-01 23:59:59') OR Stamp BETWEEN ..., ,但我不确定在这种情况下,这会使用索引。正如@Petr所建议的那样,我会构建一个每月的专栏。

在运行主查询之前,分别计算您所需的邮票值,即

步骤1-计算所需的邮票值

步骤2-在邮票>(计算值)的地方运行查询

由于步骤2中没有计算,因此您应该能够使用索引。

如果我正确理解它,您基本上想返回邮票每月第一个邮票(减去3个小时)的所有行?如果(这是一个很大的话),您有一个固定的窗口,例如最近的6个月,您只能列举6个范围测试。但是,无论如何,我不确定索引访问是否会更快。

select *
  from transactions
 where stamp between timestamp '2010-06-01 03:00:00' and timestamp '2010-06-02 02:59:59'
    or stamp between timestamp '2010-07-01 03:00:00' and timestamp '2010-07-02 02:59:59'
    or stamp between timestamp '2010-08-01 03:00:00' and timestamp '2010-08-02 02:59:59'
    or stamp between timestamp '2010-09-01 03:00:00' and timestamp '2010-09-02 02:59:59'
    or stamp between timestamp '2010-10-01 03:00:00' and timestamp '2010-10-02 02:59:59'
    or stamp between timestamp '2010-11-01 03:00:00' and timestamp '2010-11-02 02:59:59'
    or stamp between timestamp '2010-12-01 03:00:00' and timestamp '2010-12-02 02:59:59';

NB!我不确定时间戳的毫秒如何工作。您可能需要相应地垫。

重新加工PETR的答案,以避免在子句中,并为Myisam或Innodb做出。

对于迈萨姆

ALTER TABLE Transactions ADD INDEX cover_1 (PK, Stamp)

或者,对于InnoDB,PK隐含在每个索引中,

ALTER TABLE Transactions ADD INDEX Stamp (Stamp)

然后

SELECT * 
FROM Transactions LEFT JOIN
  (
  SELECT PK 
  FROM Transactions 
  WHERE DAYOFMONTH(Stamp - interval 3 hour) = 1
  ) a ON Transactions.PK=a.PK

该子查询将仅执行索引,外部查询只会从A.PK通过的表中拉出行。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top