【问题标题】:Divide single digit into ranges将单个数字划分为范围
【发布时间】:2019-02-14 09:23:18
【问题描述】:

我想不出在 PHP 中将数字划分为范围的方法。

我有大量的 MySQL 数据库记录集,想为我的脚本分散一些工作量。

例子:

表中有 2435 行,我希望每个 PHP 脚本只选择特定范围的记录:

Script 1: select [1 to 150];
Script 2: select [151 to 270];

主要问题:我想不出一种方法如何将 2435 划分为偶数范围并将它们传递给 MySQL SELECT。

【问题讨论】:

  • MYSQL LIMIT、OFFSET 怎么样?
  • 你有什么规则要划分行吗?以自然的、非技术性的方式写下来可能有助于理解问题

标签: php math divide


【解决方案1】:

像这样尝试-

SELECT * FROM table_name ORDER BY id ASC LIMIT 150 OFFSET 0

对于第一个脚本,

LIMIT 150 OFFSET 0

然后对于第二个脚本

LIMIT 150 OFFSET 150

等等……

【讨论】:

  • 你能从你的第二个和第三个例子中删除逗号吗?它们会导致语法错误。
  • 这个解决方案看起来不错,但是表中的总行数是动态值并且可以显着增加。我需要一些方法来将该动态值划分为范围。今天是 5000,明天是 10756。嗯,我想我可以将动态行数分成块,并生成每个脚本所需的具有静态偏移量的尽可能多的实例。实施后,我将发布完整的解决方案。
【解决方案2】:

因此,几天来我一直在测试偏移量在处理大量数据集(100+k 行)时的表现,结果非常糟糕。如果您的数据库中有大量行,偏移量非常消耗资源,并且绝对不适合该任务。

我的最终代码如下(抽象):

chunker.php

// Divide table rows into 50 chunks and produce array
$rows = DB::query("SELECT id FROM data_set GROUP BY id DESC");
$chunks = array_chunk($rows, 50, TRUE);

// Extract endings of each chunk array
$ends = array();
foreach ($chunks as $c) {
        $f = flattenArray($c);
        $arr_end = end($f);
        array_push($ends, $arr_end);
}

// Spawn separate PHP processes to work with a chunk array ending
foreach ($ends as $e) {
    $bb = shell_exec("php -q worker.php '".$e."' > /dev/null &");
}

worker.php

// Catch argv
$exec_args = $_SERVER['argv'];

// Select predefined amount of rows from DB which is more than or equal to argv value
$data = DB::query("SELECT * FROM data_set WHERE id >= %i LIMIT 50", $exec_args[1]);

foreach ($data as $d) {
 // Do you stuff here
}

此改编来自这篇文章http://mysql.rjweb.org/doc.php/pagination

性能方面,我偏移数据需要 8 个 CPU 内核和 32 GB RAM。使用 LIMIT 方法,我只需要 4 GB RAM 和 2 个 CPU。因此,在 LARGE 数据集中使用偏移量之前,请三思。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-06
    • 2011-12-16
    • 2020-04-29
    • 2022-01-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多