Индексирование больших БД с помощью Lucene / PHP

Добрый день, ребята,

Попытка проиндексировать таблицу с 1,7 миллиона строк с помощью Zend-порта Lucene. В небольших тестах из нескольких тысяч строк он работал отлично, но как только я пытаюсь увеличить количество строк до нескольких десятков тысяч, он выходит из строя. Очевидно, я мог бы увеличить время, в течение которого php разрешает запуск скрипта, но, учитывая, что 360 секунд дают мне ~ 10 000 строк, мне не хотелось бы думать, сколько секунд потребуется, чтобы выполнить 1,7 миллиона.

Я также попытался запустить скрипт несколько тысяч, обновить, а затем запустить следующие несколько тысяч, но при этом индекс каждый раз очищается.

Есть идеи, ребята?

Спасибо :)


person Tom    schedule 14.04.2010    source источник
comment
Несколько 10 тысяч строк по-прежнему микроскопичны, если вы теряете время, что-то действительно не так, пожалуйста, опубликуйте свой SQL и, возможно, даже информацию о вашем сервере (cpu, ram).   -  person TravisO    schedule 14.04.2010


Ответы (3)


Мне жаль это говорить, потому что разработчик Zend_Search_Lucene - мой друг, и он очень много над этим работал, но, к сожалению, он не подходит для создания индексов для наборов данных любого нетривиального размера.

Используйте Apache Solr для создания индексов. У меня есть проверено, что Solr работает более чем в 300 раз быстрее, чем Zend при создании индексов.

Вы можете использовать Zend_Search_Lucene для выполнения запросов к индексу, созданному вами с помощью Apache Solr.

Конечно, вы также можете использовать расширение PHP PECL Solr, которое я бы порекомендовал.

person Bill Karwin    schedule 17.04.2010
comment
Билл, спасибо за внимание, я перешел на использование Solr и получил 1,7 миллиона строк, проиндексированных примерно за 8 минут; разве это не согревает тебя внутри? Однако я столкнулся с одной проблемой ... stackoverflow.com/questions/2668279/, но это определенно был правильный шаг, спасибо! - person Tom; 20.04.2010

Попробуйте ускорить его, выбрав только нужные вам поля из этой таблицы.

Если это что-то, что нужно запускать как cronjob или worker, тогда он должен запускаться из CLI, и для этого я не понимаю, почему изменение тайм-аута было бы плохим. Вам нужно создать индекс только один раз. После этого новые записи или обновления к ним будут лишь небольшими обновлениями в вашей базе данных Lucene.

person Htbaa    schedule 14.04.2010
comment
Спасибо за быстрый ответ Htbaa :) Я только что избавился от 2 полей, так что теперь их только 3 (идентификатор, название компании и почтовый индекс). Я просто провожу несколько тестов и посмотрю, как это улучшит ситуацию. Увеличить время выполнения и позволить ему занять столько времени, сколько потребуется, - это вариант, хотя его сложно тестировать;) Мне нужно изучить обновление индекса Lucene, так как я не знал, что вы действительно можете? Еще раз спасибо! - person Tom; 14.04.2010
comment
См. framework.zend.com/manual/en/ для обновления документов и указателя. - person Htbaa; 14.04.2010

Некоторая информация для всех вас - публикация в качестве ответа, чтобы я мог использовать стили кода.

$sql = "SELECT id, company, psearch FROM businesses";
$result = $db->query($sql);     // Run SQL

$feeds = array();

$x = 0;
while ( $record = $result->fetch_assoc() ) {
    $feeds[$x]['id'] = $record['id'];
    $feeds[$x]['company'] = $record['company'];
    $feeds[$x]['psearch'] = $record['psearch'];
    $x++;   
}

//grab each feed

foreach($feeds as $feed) {  
  $doc = new Zend_Search_Lucene_Document();  

    $doc->addField(Zend_Search_Lucene_Field::UnIndexed('id',  
    $feed["id"]));  

  $doc->addField(Zend_Search_Lucene_Field::Text('company',  
    $feed["company"]));  

    $doc->addField(Zend_Search_Lucene_Field::Text('psearch',  
    $feed["psearch"]));  

    $doc->addField(Zend_Search_Lucene_Field::UnIndexed('link',  
    'http://www.google.com'));  


  //echo "Adding: ". $feed["company"] ."-".$feed['pcode']."\n";  

  $index->addDocument($doc);  
}  



$index->commit();

(Я использовал google.com как временную ссылку)

Сервер, на котором он работает, представляет собой локальную установку Ubuntu 8.10, 3 Гб оперативной памяти и чип Dual Pentium 3,2 ГГц.

person Tom    schedule 15.04.2010
comment
Почему у вас двойной цикл? Похоже, вы вполне могли бы обойтись одним циклом. - person Glen Solsberry; 16.04.2010
comment
Я хотел бы поделиться с вами некоторыми советами по производительности: 1- вы попадаете в 2 цикла, каждый из которых имеет 1,7 миллиона записей ......... 2- Zend_Db_Table_Abstract :: setDefaultMetadataCache ($ cache); что значительно ускорит ваши запросы - person tawfekov; 16.04.2010