代码之家  ›  专栏  ›  技术社区  ›  Ali

内存/优化问题

  •  1
  • Ali  · 技术社区  · 16 年前

    我正在编写一个复杂的脚本,它可以处理多达500000条记录。这是我的问题。

    基本上,我的代码将解析一个文本文件来获取50万条左右的记录。每个记录都有一个类别,我的代码需要检查 categories 表是在特定处理过程中为该类别创建的,如果没有,它将创建该记录。

    所以我有两个选择:

    1)我存储了一个包含类别名称和ID的键数组=>值,因此我可以这样做:

    if (array_key_exists($category,$allCategories))
       $id=$allCategories[$category];
    else
    {
       mysql_query("INSERT INTO categories (procId,category) 
                           VALUES ('$procId''$category')");
       $id=mysql_insert_id();
       $allCategories[$category]=$id;
    }
    

    2)每次处理此文本文件时,它都会获得自己的进程ID。因此,不必检查 $allCategories 变量可以增加到100000多个条目,我可以这样做:

    SELECT id FROM categories WHERE procId='$procId' AND category='$category'
    

    缺点是,这个查询将针对500000多条记录中的每一条运行。而将所有类别保存在一个数组中的缺点是我可能会耗尽内存,或者服务器可能崩溃。

    有什么想法吗?

    3 回复  |  直到 16 年前
        1
  •  2
  •   Eric Petroelje    16 年前

    你能保留一个已经插入的ID列表吗?如果它们是整数ID,那么每10万个条目就需要4个字节,而内存只有约400K。

    埃塔:

    要避免存储类别名称,请散列名称并存储散列。对于一个128位的MD5散列,每个散列有16个字节,或者只有大约1.6MB的内存+开销。

        2
  •  1
  •   Tahir Akhtar    16 年前

    一个想法是在表上添加一个约束,以便数据库拒绝重复的插入。 然后继续插入所有记录,让数据库进行检查。

        3
  •  1
  •   Georg Schölly Crazy Developer    16 年前

    考虑到您的平均类别名称是30字节,您只需要30*500000字节=15000000字节=15000千字节=1.5兆字节。

    我觉得你的记忆力很强。