PHP 加载结构化文件的速度更快


PHP loading structed files faster

>我有多个数据集,如下所示,我想使用PHP处理它们。

Dataset #1 (75 cols * 27,000 rows)
          col #1 col #2 ...
record #1
record #2
...
Dataset #2 (32 cols * 7,500 rows)
....
Dataset #3 (44 cols * 17,500 rows)
....

在这里,记录和列的数量不同,因此很难使用数据库结构。请注意,数据集的每个"单元格"仅由实数或 N/A 组成。并且数据集是完全固定的,即不会有任何变化。

因此,到目前为止,我所做的是将它们制作为基于文件的表,并在文件中写入每条记录的起始偏移量。使用这种方式,实现了相当不错的访问加速,但到目前为止还不令人满意,因为对每条记录的访问都需要将其解析为 PHP 数据结构

我最终想要实现的是消除解析步骤。但是序列化不是一个好的选择,因为它加载了整个数据集。当然,可以像我所做的那样序列化每条记录并保留它们的偏移量,但没有序列化,但我似乎并不那么花哨

所以这里有一个问题,有没有办法加载数据集的一部分,没有任何解析步骤但比我建议的部分序列化更好?

提前非常感谢。

  • 更多信息

也许我让观众有点困惑。每个数据集都是分开的,它们作为独立的文件存在。

通常的数据访问模式是按行访问的。每行都有唯一的字符串 ID,一个数据集中的 ID 可以存在于其他数据集中,但不一定。但除此之外,我关心的是当我有一些查询来获取数据集中的特定行时加快访问速度。例如,让我们有一个如下所示的数据集。

Dataset #1 (plain-text file)
     obs1  obs2  obs3  ...
my1  3.72  5.28  10.22 ...
xu1  3.44  5.82  15.33 ...
...
qq7  8.24  10.22 47.54 ...

并且有一个相应的索引文件,使用 PHP 序列化。每个项的键表示数据集中的唯一 ID,其值表示它们在文件中的偏移量

Index #1 (PHP-serialized one, not same as actual serialized one)
Array (
  "my1" => 0,
  "xu1" => 337,
  ...
  "qq7" => 271104
)

因此,可以知道记录"xu1"从数据集文件的开头开始于337字节。为了使用其唯一 ID 访问和获取某些行,

1) Load serialized index file
2) Find matching IDs with query
3) Access to those position and fetch rows, and parsing them as an array of PHP.

我遇到的问题是

1) Since I using exact matching, it is impossible to fetch multiple rows that partially matching with query (for example, fetch "xu1" row from query "xu")
2) Even though I indexed dataset, fetch speed is not satisfactory (took 0.05 sec. from single query)
3) When I tried to solve above problem by serializing an entire dataset, (maybe of course) the loading speed become substantially slower.

解决上述问题的唯一最简单的方法是将它们作为数据库,我会这样做,但希望找到更好的方法,将它们保留为纯文本或一些类似文本的格式(例如,序列化或 JSON 编码)。

非常感谢和对我的问题感兴趣!

我想我在某种程度上理解你的问题。你有 3 组数据,可以相关,也可以不相关,列和行数不同。

这可能不是最干净的解决方案,但我认为它可以解决目的。您可以使用 mysql 来存储数据,以避免不时解析文件。您可以将数据存储在三个表中,也可以将它们放在一个包含所有列的表中(不需要设置列的行可以为字段值提供"null")。

您还可以使用

sql 联合,以防您想在所有三个数据集上共同运行查询,方法是使用诸如

select null as "col1", col2, col3 from table1 where col2="something"
union all
select col1,null as "col2", null as "col3" from table2 where co1="something else"
order by col1