代码之家  ›  专栏  ›  技术社区  ›  Jason Swett

我怎样才能更快地做到这一点?

  •  0
  • Jason Swett  · 技术社区  · 14 年前

    customer 还有一个叫 address ,其中 地址 customer_id .

    对我来说重要的一点是不要有任何重复的行。因此,每次导入地址时,我都会执行以下操作:

    $address = new Address();
    $address->setLine_1($line_1);
    $address->setZip($zip);
    $address->setCountry($usa);
    $address->setCity($city);
    $address->setState($state);
    $address = Doctrine::getTable('Address')->findOrCreate($address);
    $address->save();
    

    findOrCreate() 您可能猜到,如果存在匹配的地址记录,则只返回一个新的地址记录。 Address

      public function findOrCreate($address)
      {
        $q = Doctrine_Query::create()
          ->select('a.*')
          ->from('Address a')
          ->where('a.line_1 = ?', $address->getLine_1())
          ->andWhere('a.line_2 = ?', $address->getLine_2())
          ->andWhere('a.country_id = ?', $address->getCountryId())
          ->andWhere('a.city = ?', $address->getCity())
          ->andWhere('a.state_id = ?', $address->getStateId())
          ->andWhere('a.zip = ?', $address->getZip());
    
        $existing_address = $q->fetchOne();
    
        if ($existing_address)
        {
          return $existing_address;
        }
        else
        {
          return $address;
        }
      }
    

    这样做的问题是速度太慢。保存CSV文件中的每一行 INSERT

    4 回复  |  直到 14 年前
        1
  •  1
  •   mway    14 年前

    这当然不会减少花费在数万次迭代上的所有时间,但是为什么不在每次迭代的DB查询之外管理您的地址呢?总体思路:

    1. 获取所有当前地址的列表(将其存储在数组中)
    2. 在迭代时,检查数组成员(校验和[SiC]);如果不存在,则将新地址存储在数组中,并将地址保存到数据库中。

    除非我误解了这个场景,否则您只需要在必要时进行INSERT查询,并且除了第一个查询之外,您不需要执行任何SELECT查询。

        2
  •  1
  •   Ike Walker    14 年前

    我建议您使用 LOAD DATA INFILE :

    http://dev.mysql.com/doc/refman/5.1/en/load-data.html

    加载数据填充 REPLACE 选项,您可以使用它来更新现有行,但您需要确保有一个适当的唯一索引,而替换实际上只是一个 DELETE INSERT ,这比 UPDATE .

    INSERT...ON DUPLICATE KEY UPDAT E、 同样,请确保您有一个适当的唯一索引,但在这种情况下,您是在执行更新而不是删除,因此应该更快。

        3
  •  0
  •   Alan Geleynse buhbang    14 年前

    EXPLAIN 在上面。

    我猜你需要创建一些索引。搜索整个表可能非常慢,但是向zip添加索引将允许查询只对具有该邮政编码的地址执行完整搜索。这个 将能够指导您进行其他优化。

        4
  •  0
  •   Jason Swett    14 年前

    ON DUPLICATE KEY UPDATE 而不是使用 findOrCreate() .