PHP 对大量数据的自然排序内存问题


PHP's natural sort memory issue on huge amount of data

我使用的是php的自然排序算法natsort但我对内存使用有一个考虑。

事情就是这样。脚本从 mysql 中提取数据并将结果放入数组中,然后在其上应用natsort。但这里有一个问题。行的文本可能很长,可能有数百行。

示例代码:

$array = array();
while ($row = $db->getResults()) {
  $array[$row->code] = $row->text;
}
if (empty($array)) {
  uksort($array, "strnatcmp");
}

我想知道这对记忆有什么影响?这是合适的方法,还是我应该做一些更有效、更令人愉悦的记忆力的事情?

您可以做的一件事是存储一个新列,该列复制要排序的列,但将其以转换后的格式存储,该格式在使用常规排序算法时自然排序。

概念上讲,您可以通过左填充数字序列(零)的长度与字符串中可能出现的最长数字序列一样长来执行此操作。

我的解决方案并不完全坚固,但是如果您的字符串只有已知最大长度的数字序列,那么您可以将它们与已知最大长度的零一起填充。例如,如果您有 cd 曲目标题,并在标题中嵌入了曲目编号,例如:

1 Foo
2 Bar
...
10 Baz

也许您决定最长的数字序列可能是 3(999 个可能的轨道),因此您会像

001 Foo
002 Bar
...
010 Baz

这适用于具有多个数字序列的字符串。

示例 php 代码,尽管您可以编写一个 mysql 存储函数来执行此操作,然后在表上使用插入和更新触发器,以便透明地维护它。

$input = 'a44b1c399d4';
$nat = preg_replace_callback('#'d+#', function($m) {
    return str_pad($m[0], 3, '0', STR_PAD_LEFT);
}, $input);
echo $nat; // a044b001c399d004

然后只需在 mysql 中排序即可通过

order by natsort_column

这还允许您在该列上放置索引,从而为您提供良好的排序性能。

你需要

使用 MySQL WHEREGROUP BYORDER BY 子句,这样你就不会在 PHP 级别浪费时间解析数千条不需要的记录。