Drupal 7 数据库 API 与 PHP mysqli_connect() 相比非常慢


Drupal 7 database API very slow compared to PHP mysqli_connect()

我正在尝试循环访问来自SOAP请求的一些数据,并将记录插入到Drupal安装中的自定义表中。

起初,我创建了一个自定义模块,并使用标准mysqli_connect()语法连接到数据库并循环访问记录并插入它们。这工作得很好,并在大约 2 秒内顺利获取并插入了我的远程数据。

然后我想起Drupal有一个数据库API(我对Drupal相当陌生),所以我决定做正确的事情并使用API。我将我的代码转换为我认为应该按照 API 文档执行的方式,但现在该过程需要 5 或 6 秒,有时甚至随机挂起并且根本无法完成,我得到奇怪的会话错误。记录最终插入得很好,但只是需要永远。

想知道我是否做错了。我还想将插入包装到事务中,因为我将首先删除目标表中的所有记录,然后插入新数据,并且由于我首先删除,我希望能够在插入失败时回滚由于任何原因。

我没有将事务代码添加到我原来的 PHP 代码中,但确实尝试使用 Drupal API 进行尝试,尽管完全删除事务/try/catch 代码似乎根本不影响速度或问题。

无论如何,这是我的原始代码:

$data = simplexml_load_string($jobsXml);
$connection = mysqli_connect("localhost","user","pass","database");
if (mysqli_connect_errno($connection))
{
  echo "Failed to connect to MySQL: " . mysqli_connect_error();
  exit();
}
// delete * current jobs
mysqli_query($connection,'TRUNCATE TABLE jobs;');
$recordsInserted = 0;
foreach ($data->NewDataSet->Table as $item) {
  //escape and cleanup some fields
  $image = str_replace('http://www.example.com/public/images/job_headers/', '', $item->job_image_file);
  $specialty_description = mysqli_real_escape_string($connection, $item->specialty_description);
  $job_board_title = mysqli_real_escape_string($connection, $item->job_board_title);
  $job_board_subtitle = mysqli_real_escape_string($connection, $item->job_board_subtitle);
  $job_state_code = ($item->job_country_code == 'NZ') ? 'NZ' : $item->job_state_code;
  $sql =  "
  INSERT INTO jobs (
    job_number,
    specialty,
    specialty_description,
    division_code,
    job_type,
    job_type_description,
    job_state_code,
    job_country_code,
    job_location_display,
    job_board_type,
    job_image_file,
    job_board_title,
    job_board_subtitle
  ) VALUES (
    $item->job_number,
    '$item->specialty',
    '$specialty_description',
    '$item->division_code',
    '$item->job_type',
    '$item->job_type_description',
    '$job_state_code',
    '$item->job_country_code',
    '$item->job_location_display',
    '$item->job_board_type',
    '$image',
    '$job_board_title',
    '$job_board_subtitle'
  )
  ";
  if (!mysqli_query($connection,$sql))
  {
    die('Error: ' . mysqli_error($connection) . $sql);
  }
    $recordsInserted++;
}
mysqli_close($connection);
echo $recordsInserted . ' records inserted';

这是我的Drupal代码。谁能告诉我我是否做错了,或者不是最有效的方法?

$data = simplexml_load_string($jobsXml);
// The transaction opens here.
$txn = db_transaction();  
// delete all current jobs
$records_deleted = db_delete('jobs')
->execute();  
$records_inserted = 0;
try {
  $records = array();
  foreach ($data->NewDataSet->Table as $item) {
    $records[] = array(
      'job_number' =>  $item->job_number,
      'specialty' => $item->specialty,
      'specialty_description' => $item->specialty_description,
      'division_code' => $item->division_code,
      'job_type' => $item->job_type,
      'job_type_description' => $item->job_type_description,
      'job_state_code' => ($item->job_country_code == 'NZ') ? 'NZ' : $item->job_state_code,
      'job_country_code' => $item->job_country_code,
      'job_location_display' => $item->job_location_display,
      'job_board_type' => $item->job_board_type,
      'job_image_file' => str_replace('http://www.example.com/public/images/job_headers/', '', $item->job_image_file),
      'job_board_title' => $item->$job_board_title,
      'job_board_subtitle' => $item->job_board_subtitle,
    );      
    $records_inserted++;
  }
  $fields = array(
    'job_number',
    'specialty',
    'specialty_description',
    'division_code',
    'job_type',
    'job_type_description',
    'job_state_code',
    'job_country_code',
    'job_location_display',
    'job_board_type',
    'job_image_file',
    'job_board_title',
    'job_board_subtitle'
  );
  $query = db_insert('jobs')
    ->fields($fields);
  foreach ($records as $record) {
    $query->values($record);
  }
  $query->execute();
} catch (Exception $e) {
  // Something went wrong somewhere, so roll back now.
  $txn->rollback();
  // Log the exception to watchdog.
  watchdog_exception('Job Import', $e);
  echo $e;
}
echo  $records_deleted . ' records deleted<br>';
echo  $records_inserted . ' records inserted';

您尝试插入的数据集有多大?如果数据集非常大,那么也许您可能会遇到查询大小问题。尝试循环访问记录并像使用 PHP 一样逐个插入每个记录。