这个问题听起来有点笼统。仍然。 我们有一个包含数亿条记录的表。 为了制作这份报告,其他几个较小的表格正在加入其中。 为所有适当的列创建索引。 客户希望获得一年以上的报告,可能多达 1 亿行。
为了确保进程安全,比如说如果脚本终止,或者如果与数据库的连接断开,则必须分块提取报告,以便下一个进程从前一个终止的地方获取报告。
问题是报告可以按varchar/int列进行排序,其中可以包含客户姓名、帐号、不同格式的各种个人数据等,我还没有整理出如何获得合理数量的在这些情况下,每个 block 的行数(比如 ~50k)。
对于这种数据量,使用 limit x,y 将花费太长时间。 没有归档表,没有分区,数据没有聚合到单独的表中。一张表中只有一大块数据。
有没有一种既定的(神奇的?)方法来处理这类问题?
最佳答案
“有没有一种既定的(神奇的?)方法来处理这类问题?” -- 你问的是我花了很多时间完善的几件事。
“数以亿计的记录...报表”和“报表可以按各种列排序”——使用汇总表,可以运行得更快:http://mysql.rjweb.org/doc.php/summarytables .汇总表有助于排序。
“索引是为所有适当的列创建的”——抱歉我的愤世嫉俗,但我发现这个短语意味着你有一堆单列INDEXes
,但还没有了解合适的“复合”索引的好处。 http://mysql.rjweb.org/doc.php/index_cookbook_mysql和 http://mysql.rjweb.org/doc.php/index1
“使用 LIMIT 和 OFFSET”——这就是它非常低效的原因:http://mysql.rjweb.org/doc.php/pagination .我没有看到需要 OFFSET
来解决您的问题。 “记住你离开的地方”可能有助于最初构建汇总表。
“与数据库的连接下降”——以上提示应该足够快以避免这个问题。如果没有,请提供 SHOW CREATE TABLE
、SELECT
以及可能的其他详细信息。
“分块”——这里有一些关于分块的技巧,但我认为这不是手头问题的解决方案:http://mysql.rjweb.org/doc.php/deletebig#deleting_in_chunks
“数亿条记录......在一张表中”——没问题。我的提示是针对那个尺寸的。
“无分区”——很好。我不必花时间说服您分区不太可能有帮助:http://mysql.rjweb.org/doc.php/partitionmaint
您中奖了。我想我从来没有指着我的 6 个博客来回答一个问题。
关于php - 从 block 中的大表中提取报告,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56777991/