Специфика Views 3 такова, что если в представление добавлены поля Field API (использующие views_handler_field_field
), то после выполнения запроса к БД вызывается функция entity_load()
, которая подгружает все сущности из результатов выборки (см. views_handler_field_field::post_execute()).
При выводе большого числа результатов это создаёт большие накладные расходы, так как за entity_load()
стоит hook_entity_load()
, на который сторонние модули любят вешать дополнительные sql-и-не-только запросы.
Из ситуации можно выйти вот таким вот нехитрым способом:
/**
* Implements hook_views_data_alter().
*/
function MODULENAME_views_data_alter(&$data) {
foreach ($data as $table_name => $table_info) {
foreach ($table_info as $field_name => $field_info) {
if (isset($field_info['field']['handler']) && $field_info['field']['handler'] == 'views_handler_field_field') {
$field_info['field']['handler'] = 'views_handler_field';
$field_info['title'] .= ' (raw)';
$field_info['title short'] .= ' (raw)';
$data[$table_name][$field_name . '_raw'] = $field_info;
}
}
}
}
Здесь на каждое Field API поле, создаётся его "raw" аналог с хэндлером views_handler_field
, который не дёргает entity_load()
:
Хэндлер выводит сырое значение из БД. Форматтеры не доступны, предполагается использование темизации или альтеринга.
Результаты тестов производительности на примере вывода 1000 нод:
Число запросов | Время выполнения всех запросов | Время генерации страницы | |
---|---|---|---|
Вывод только поля title | 39 | 11 ms | 600 ms |
Вывод поля title и body | 49 | 80 ms | 1400 ms |
Вывод поля title и body (raw) | 40 | 30 ms | 900 ms |
Итого: при отказе от entity_load()
получили уменьшение времени генерации страницы почти на 40%. Причём чем больше включено модулей, использующих hook_entity_load()
, тем этот выигрыш будет больше. Тесты проводились на голом друпале.
Комментарии
Огромное спасибо))
Спасибо Вам большое!
Добавить комментарий