PHP加载结构化文件更快

时间:2014-04-07 02:35:13

标签: php database serialization

我有多个数据集,如下所示,我想用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编码)。

非常感谢和关注我的问题!

1 个答案:

答案 0 :(得分:0)

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

这可能不是最干净的解决方案,但我认为它可以解决目的。您可以使用mysql存储数据,以避免一次又一次地解析文件。您可以将数据存储在三个表中,也可以将它们放在一个包含所有列的表中(不需要set列的行可以为字段值设置为“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