Доброго времени суток.
Как можно быстро удалять ноды в количестве ~1000 в час по крону. пробовал node_delete_multiple() по 150 шт., но при этом БД зависает и не отвечает секунд 30. Как можно это решить? Если удалять все sql-запросами, какие таблицы(кроме таблиц node, node_revision, field_data_field_* ) надо очищать?
Комментарии
Через кую попробуй см. модуль aggregator
Что-то подобное получилось:
<?php
/*
function d($nids)
{
$entity_type = 'node';
$bundle = NODE_TYPE_PAGE;
$all_field_instatnces = field_info_instances($entity_type, $bundle);
foreach($all_field_instatnces as $field_name => $field_instance)
{
$field_info = field_info_field($field_name);
if($field_info['type'] == 'image' || $field_info['type'] == 'file')
{
// удаляем файлы, привязанные к ноде
$file_q = db_select('field_data_'.$field_name, 'fd')->fields('fd', $field_name.'_fid');
$file_q->condition('fd.entity_id', $nids, 'IN');
$file_q->condition('fd.bundle', $bundle);
$file_q->condition('fd.entity_type', $entity_type);
$del_fids = $file_q->execute()->fetchCol();
file_delete_multiple() может выполнятся долго, в зависимости от количества файлов
в ноде.
*/
file_delete_multiple($del_fids);
}
$fr_q = db_delete('field_revision_'.$field_name);
$fr_q->condition('entity_id', $nids, 'IN');
$fr_q->condition('bundle', $bundle);
$fr_q->condition('entity_type', $entity_type);
$fr_q->execute();
$nr_q = db_delete('node_revision');
$nr_q->condition('nid', $nids, 'IN');
$nr_q->condition('bundle', $bundle);
$nr_q->condition('entity_type', $entity_type);
$nr_q->execute();
$f_q = db_delete('field_data_'.$field_name);
$f_q->condition('entity_id', $nids, 'IN');
$f_q->condition('bundle', $bundle);
$f_q->condition('entity_type', $entity_type);
$f_q->execute();
$n_q = db_delete('node');
$n_q->condition('nid', $nids, 'IN');
$n_q->condition('bundle', $bundle);
$n_q->condition('entity_type', $entity_type);
$n_q->execute();
}
}
?>
node_load_multiply + node_delete - наше ВСЁ!
node_delete по одной ноде работает быстрее node_delete_multiple? Развейте мои сомнения, пожалуйста.
Сейчас у меня работает всё через node_delete_multiple и меня это не устраивает. Мне нужна скорость, и я сознательно хочу пренебречь ради этого принципами друпала и не использовать эти функции, т.к. они работают медленно в моих условиях.
- node_load_multiple - есть в API
- node_delete_multiple - а это что такое ?
тут только через batch можно делать, иначе ваша БД так и будет ложиться, пока хостеру это не надоест и он не заблочит ваш акк.
Вы куда-то очень торопитесь или вам нужно просто, чтобы не происходил сбой при удалении?
Тороплюсь. Если уменьшить количество - ноды начинают копиться.
а через batch пробовали или нет? Там суть в том, что он может любое количество транзакций провернуть в фоне, по одной ноде за транзакцию. Понятно, что это не очень быстро, но сбой происходить не будет, никаких зависаний и таймаутов не произойдёт - всё должно будет отработать штатно.
ЗЫ: а что за прикол такой, что если удалять меньше тысячи нод в час, то они копятся? Может сперва нужно остановить генерацию нового мусора, а потом уже чистить то, что есть?
Попробую ещё раз раз - queue
За queue спасибо. Это оно.
Есть node_load, а есть node_laod_multiple.
Есть node_delete, а есть node_delete_multiple. Вот ссылка на API.
Для этой задачи - не пробовал. Ну, точнее, пробовал, стандартное удаление нод сделано через batch, я его использовал и мне не понравилось. Теоретически его можно использовать, но что лучше batch или queue я пока не знаю. batch ограничивается количеством, queue - временем.
Ноды не сразу становятся мусором. Они создаются, с ними работают, по истечении какого-то срока их нужно удалить.
Я использовал консольный скрипт когда нужно было удалить 500 000 нод за короткое время.
В вашем случае до 100 000 нод ,батч всегда отлично справится.
В вашем случае Queue API
Та да, есть такой, imho queue как раз для Вашей задачи