从 mysql 获取大结果集

Posted

技术标签:

【中文标题】从 mysql 获取大结果集【英文标题】:Get big result set from mysql 【发布时间】:2014-03-16 23:03:25 【问题描述】:

我有一个包含大约 2000 万行的大表,并且它每天都在增长,并且我有一个从该表中获取查询的表单。不幸的是,查询返回数十万行。 查询是基于时间的,我需要所有记录根据一些规则通过'clid'对它们进行分类。所以我需要对所有记录进行一些处理以制作结果表。 这是我的桌子:

    CREATE TABLE IF NOT EXISTS `cdr` (
  `gid` bigint(20) NOT NULL AUTO_INCREMENT,
  `prefix` varchar(20) NOT NULL DEFAULT '',
  `id` bigint(20) NOT NULL,
  `start` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
  `clid` varchar(80) NOT NULL DEFAULT '',
  `duration` int(11) NOT NULL DEFAULT '0',
  `service` varchar(20) NOT NULL DEFAULT '',
  PRIMARY KEY (`gid`),
  UNIQUE KEY `id` (`id`,`prefix`),
  KEY `start` (`start`),
  KEY `clid` (`clid`),
  KEY `service` (`service`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf-8 ;

这是我的查询:

SELECT * FROM `cdr` 
    WHERE 
        service = 'test' AND 
        `start` >= '2014-02-09 00:00:00' AND 
        `start` < '2014-02-10 00:00:00' AND 
        `duration` >= 10

日期周期可能从 1 小时到 60 天甚至更长。(如:

“2013-02-02 00:00:00”和“2014-02-03 00:00:00”之间的日期(开始)

)

结果集每天大约有 150,000 行。当我尝试获得更长时期甚至一天的结果时,数据库崩溃。 有人知道吗?

【问题讨论】:

您是否尝试过使用 mysqlLIMITOFFSET 批量获取结果,例如 10,000 行?获得所有结果需要更长的时间,但有助于解决超时错误。 是的,但这需要很长时间,因为它应该是实时报告,所以我的老板不能接受这么长时间。 【参考方案1】:

我不知道如何防止它崩溃,但我对我的大表所做的一件事是按日期对它们进行分区。

在这里,我按日期对行进行分区,每月两次。只要您的查询使用分区列,它就只会搜索包含该键的分区。它不会进行全表扫描。

CREATE TABLE `identity` (
  `Reference` int(9) unsigned NOT NULL AUTO_INCREMENT,
  ...
  `Reg_Date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
  PRIMARY KEY (`Reference`),
  KEY `Reg_Date` (`Reg_Date`)
) ENGINE=InnoDB AUTO_INCREMENT=28424336 DEFAULT CHARSET=latin1
PARTITION BY RANGE COLUMNS (Reg_Date) (

  PARTITION p20140201 VALUES LESS THAN ('2014-02-01'),
  PARTITION p20140214 VALUES LESS THAN ('2014-02-14'),
  PARTITION p20140301 VALUES LESS THAN ('2014-03-01'),
  PARTITION p20140315 VALUES LESS THAN ('2014-03-15'),
  PARTITION p20140715 VALUES LESS THAN (MAXVALUE)

);

所以基本上,您只需转储表,使用分区创建它,然后将数据导入其中。

【讨论】:

谢谢,我会尽力告诉你结果。 分区前我和老板谈过,说服他改变报告结构。通过删除报告的某些字段,我能够在 mysql 中执行 SUM、AVG、COUNT、DISTINCT 等所有功能,并返回一个小的结果集。它确实帮助了我,但随着数据库的快速增长,分区将是我的下一个防止惰性查询的步骤。

以上是关于从 mysql 获取大结果集的主要内容,如果未能解决你的问题,请参考以下文章

使用mysql jdbc获取快速结果集

MySQL 存储过程,获取使用游标查询的结果集

为啥 MySQL 给出错误“不允许从函数返回结果集”?

联表查询时始终以小结果集驱动大结果集

mysql -- 动态获取结果集(重点)

记一次ES查询结果集失败