MYSQL:如何在不查询整个表的情况下在过去X小时内插入行
假设我有一个有一百万行的表,在过去的2小时内只添加了5行(每天每小时添加的行数不同) 例如,我希望能够获得在过去2小时内添加的行。为了获得最佳性能,我可以使用的最佳查询/实现是什么 我想避免查询整个一百万个表,每两小时比较一次日期。。。有更好的办法吗MYSQL:如何在不查询整个表的情况下在过去X小时内插入行,mysql,performance,Mysql,Performance,假设我有一个有一百万行的表,在过去的2小时内只添加了5行(每天每小时添加的行数不同) 例如,我希望能够获得在过去2小时内添加的行。为了获得最佳性能,我可以使用的最佳查询/实现是什么 我想避免查询整个一百万个表,每两小时比较一次日期。。。有更好的办法吗 谢谢。为了更好地说明@Eric的评论/问题:向我们展示您的模式 但简单的回答是,如果不涉及查询日志和数据库服务器的其他“带外”逻辑,这是不可能的 然而,这样的想法完全没有抓住关系数据库管理系统(RDBMS)的重点。对“整个”表运行查询是SQL的工作
谢谢。为了更好地说明@Eric的评论/问题:向我们展示您的模式 但简单的回答是,如果不涉及查询日志和数据库服务器的其他“带外”逻辑,这是不可能的 然而,这样的想法完全没有抓住关系数据库管理系统(RDBMS)的重点。对“整个”表运行查询是SQL的工作内容。与此相一致,如果您有一个正确指定的模式,那么以性能方式运行带有限制性WHERE子句的SELECT是RDBMS(比如文本文件)的主要增值之一
SELECT * FROM mytable WHERE last_update > NOW() - INTERVAL 2 HOUR;
如果存在像last\u update
这样的列,并且该列具有正确的数据类型和索引,那么该查询将运行得非常快。一百万行要排序?没什么。要整理的十亿行?没问题。我经常在十亿行表上运行这样的查询,并在中等级别的桌面硬件上获得亚秒级的结果
这个速度的关键是什么?适当的模式、适当的规范化和索引的适当使用。为了更好地说明@Eric的评论/问题:向我们展示您的模式 但简单的回答是,如果不涉及查询日志和数据库服务器的其他“带外”逻辑,这是不可能的 然而,这样的想法完全没有抓住关系数据库管理系统(RDBMS)的重点。对“整个”表运行查询是SQL的工作内容。与此相一致,如果您有一个正确指定的模式,那么以性能方式运行带有限制性WHERE子句的SELECT是RDBMS(比如文本文件)的主要增值之一
SELECT * FROM mytable WHERE last_update > NOW() - INTERVAL 2 HOUR;
如果存在像last\u update
这样的列,并且该列具有正确的数据类型和索引,那么该查询将运行得非常快。一百万行要排序?没什么。要整理的十亿行?没问题。我经常在十亿行表上运行这样的查询,并在中等级别的桌面硬件上获得亚秒级的结果
这个速度的关键是什么?适当的模式、适当的规范化和索引的适当使用。考虑下表中超过一百万行:
CREATE TABLE `event` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`data` varchar(11) DEFAULT NULL,
`occured_on` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
) ENGINE=InnoDB AUTO_INCREMENT=1058669 DEFAULT CHARSET=utf8;
注意:在字段上出现的没有索引
要在过去2小时内插入行,请编写:
SELECT * FROM `event` WHERE `occured_on` > NOW() - INTERVAL 2 HOUR;
但是如果你分析一下这个查询
EXPLAIN SELECT * FROM `event` WHERE occured_on > NOW() - INTERVAL 2 HOUR;
您将得到如下结果(取决于您的数据):
这基本上意味着全表扫描(ROWS条目告诉我们MySQL需要查看多少行才能找到结果集)。
现在,如果添加索引并运行相同的解释查询
ALTER TABLE `event` ADD INDEX (`occured_on`);
EXPLAIN SELECT * FROM `event` WHERE occured_on > NOW() - INTERVAL 2 HOUR;
您将看到(取决于您的数据):
这意味着MySQL只查看了5行来查找结果集。正如您所见,索引非常重要。请考虑下表中超过一百万行的内容:
CREATE TABLE `event` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`data` varchar(11) DEFAULT NULL,
`occured_on` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
) ENGINE=InnoDB AUTO_INCREMENT=1058669 DEFAULT CHARSET=utf8;
注意:在
字段上出现的没有索引
要在过去2小时内插入行,请编写:
SELECT * FROM `event` WHERE `occured_on` > NOW() - INTERVAL 2 HOUR;
但是如果你分析一下这个查询
EXPLAIN SELECT * FROM `event` WHERE occured_on > NOW() - INTERVAL 2 HOUR;
您将得到如下结果(取决于您的数据):
这基本上意味着全表扫描(ROWS条目告诉我们MySQL需要查看多少行才能找到结果集)。
现在,如果添加索引并运行相同的解释查询
ALTER TABLE `event` ADD INDEX (`occured_on`);
EXPLAIN SELECT * FROM `event` WHERE occured_on > NOW() - INTERVAL 2 HOUR;
您将看到(取决于您的数据):
这意味着MySQL只查看了5行来查找结果集。正如您所看到的,索引非常重要。行的外观如何?你有增量id吗?创建时的时间戳?有索引吗?对要筛选的列使用索引请阅读以下内容:如果您想要非纯猜测的答案,请回答您的问题。对不起,我还没有任何表格,我问这个问题是为了了解如何构造它以获得最佳性能。行是什么样子的?你有增量id吗?创建时的时间戳?有索引吗?在你想要筛选的列上使用索引请阅读以下内容:如果你想要的答案不是纯粹的猜测,那么你的问题是什么。对不起,我还没有任何表格,我问这个问题是为了了解如何构造它以获得最佳性能。(5是近似值。但比1053588好得多。)(5)是‘近似值。但比‘1053588’好多了。)谢谢你的解释。谢谢你的解释。