【发布时间】:2014-07-21 14:13:55
【问题描述】:
我有一个表,目前包含大约 500 万行。这是一个实时数据库,其中数据是通过抓取脚本填充的。脚本将数据连续插入到表中, 例如:
企业列表网站在 API 调用时给了我一个 JSON 响应,它被解析并插入到数据库中。重复检查也会在两者之间进行。在稍后阶段,我将获取他获得的数据以获取报告。
在尝试根据存储的信息获取报告时,完成脚本执行所需的时间太长。 抓取脚本是实时的,并且将来会继续使用记录更新表。 每个月它预计会获得 0.7 到 100 万条新记录。
下面是我的表结构,
CREATE TABLE IF NOT EXISTS `biz_listing` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`lid` smallint(11) NOT NULL,
`name` varchar(300) NOT NULL,
`type` enum('cat1','cat2') NOT NULL,
`location` varchar(300) NOT NULL,
`businessID` varchar(300) NOT NULL,
`reviewcount` int(6) NOT NULL,
`city` varchar(300) NOT NULL,
`categories` varchar(300) NOT NULL,
`result_month` varchar(10) NOT NULL,
`updated_date` date NOT NULL,
PRIMARY KEY (`id`),
KEY `biz_date` (`businessID`,`updated_date`),
KEY `type_date` (`type`,`updated_date`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
记录分为两类,“cat1”和“cat2”。 (我打算添加一个新类别,比如 cat3)
我需要有一个相同的站点汇总报告部分,其中显示了在选定月份范围内每个月的业务 ID。
这里选择为 2014 年 6 月至 7 月。
报告总数#类别
SELECT COUNT(t.`businessID`) AS bizcount, SUM(t.reviewcount) AS reviewcount, t.`type`
FROM `biz_listing` t
INNER JOIN
( SELECT `businessID`,count(*) c FROM `biz_listing` WHERE updated_date BETWEEN '2014/06/01' AND LAST_DAY('2014/07/01') GROUP
BY `businessID`,`type` HAVING c = 2 ) t2
ON t2.`businessID` = t.`businessID`
WHERE updated_date BETWEEN '2014/07/01' AND LAST_DAY('2014/07/01') GROUP BY t.`type`
解释(在 400 万个备份表上完成)
报告基于城市的总数#
SELECT COUNT(t.`businessID`) AS bizcount, SUM(t.reviewcount) AS reviewcount, t.`type`, t.`location` as city
FROM `biz_listing` t
INNER JOIN
( SELECT `businessID`,count(*) c FROM `biz_listing` WHERE updated_date BETWEEN '2014/06/01' AND LAST_DAY('2014/07/01') GROUP
BY `businessID`,`type` HAVING c = 2 ) t2
ON t2.`businessID` = t.`businessID`
WHERE updated_date BETWEEN '2014/07/01' AND LAST_DAY('2014/07/01') GROUP BY t.`location`, t.`result_month`
这里我们选择月份范围(六月-七月),所以它会列出两个月份范围内所有常见的businessID,
第一个查询将根据业务类型输出
第二次查询将根据位置输出
问题是执行查询需要相当长的时间(600 秒甚至更多),有时查询在完成之前就死掉了。
如果您发现,请建议我对查询进行优化。
我认为索引会影响抓取脚本的插入性能。 考虑到插入和检索性能,如何修改当前脚本?
提前感谢。
编辑
我尝试了建议的覆盖索引,它比平时花费了更多的时间:(
解释如下:
【问题讨论】:
-
你听说过解释吗?
-
@JohnRuddell Sry,我现在已经添加了。
-
好的,您是否已经设置了任何索引?日期是否以这种格式存储?感谢您的快速响应
-
尝试更改查询中日期的格式,然后..匹配格式。您也可以查看日期的 INTERVAL,这可能对速度有所帮助.. 问题在于没有索引的
HAVING子句 -
您应该尝试添加索引到任何时候进行多行比较,因此当您将一个表与另一个表连接时,您应该在两个表的 PK 和 FK 上有一个索引。这将提高速度. Ollie 的回答也有助于理解索引...我建议对其进行研究以了解添加索引的最佳方法以及连接表时的关键瓶颈在哪里(性能方面)
标签: php mysql sql indexing query-optimization