Генерация Google Sitemap для тысяч ресурсов
Итак, у вас тысяча ресурсов на сайте и вам нужно сгенерировать карту Google для сайта. С несколькими сотнями ресурсов, вы можете использовать некоторые из дополнений из репозитория (getResources, GoogleSiteMap, pdoSitemap) и при этом не будет никаких проблем с производительностью. Но что будет, если у вас 15 тыс. ресурсов?
Ответ простой, необходимое время для генерации ресурсов быстро увеличивается и вы начинаете быстро подходить к границе памяти и времени выполнения скриптов PHP. На последнем сайте, с которым я работал, пришлось решать именно эту проблему. И на ум мне прошло самое простое решение!
После обдумывания различных процессов оптимизации, я быстро понял, что получение количества ресурсов и последующая их итерация для получения
<?php
ini_set('max_execution_time', 0);
$priority = $modx->getOption('priorityId', $scriptProperties, 1);
$changeFreq = $modx->getOption('changeFreqId', $scriptProperties, 1);
$options = array(
xPDO::OPT_CACHE_KEY => 'sitemap',
);
$output = $modx->cacheManager->get('sitemap', $options);
if ($output == null) {
$output = '<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
';
$stmt = $modx->query("
SELECT
GROUP_CONCAT(
'<url>',
CONCAT('<loc>" . MODX_SITE_URL . "',uri,'</loc>'),
CONCAT('<lastmod>',FROM_UNIXTIME(editedon, '%Y-%m-%d'),'</lastmod>'),
IFNULL(
CONCAT('<priority>',(
SELECT value
FROM modx_site_tmplvar_contentvalues
USE INDEX (tv_cnt)
WHERE contentid=id AND tmplvarid={$priorityId}
),'</priority>'),''),
IFNULL(
CONCAT('<changefreq>',(
SELECT value
FROM modx_site_tmplvar_contentvalues
USE INDEX (tv_cnt)
WHERE contentid=id AND tmplvarid={$changeFreqId}
), '</changefreq>'), ''),
'</url>'
SEPARATOR ''
) AS node
FROM modx_site_content AS s
WHERE s.deleted = 0 AND s.published = 1 AND s.searchable = 1 AND context_key='web'
GROUP BY s.id
ORDER BY s.id ASC
");
if ($stmt) {
$rows = $stmt->fetchAll(PDO::FETCH_COLUMN);
$output .= implode('', $rows);
}
$output .= '</urlset>';
$modx->cacheManager->set('sitemap', $output, 86400, $options);
}
return $output;
Как вы видите, запрос установлен для получения приоритета и частоты изменений из двух ТВ - это схоже на то, как дополнения для генерации карты сайта способны устанавливать пользовательские приоритеты и частоту изменений для ресурса. Если значения не установлены специально для ресурса, он не выводит соответствующую часть ноды и будет использовать значения для Гугла по-умолчанию.
Отмечу в частности USE INDEX(tv_cnt) в подзапросах: он сообщает подзапросам использовать специальный индех привязанный к фильтрации ИД ТВ и ИД контента - без этого запрос занимал бы значительное время.
Также ещё пару вещей нужно отметить:
- Запрос ограничен ресурсами в web контексте. Если вы решите использовать этот сниппет для другого контекса, помните, что нужно обновить ключ контекста
- Вывод закеширован на 24 часа. Если нужно другое время хранения в кеше - поменяйте значение 86400 на нужное вам в секундах
- Можете свободно менять скрипт для ваших нужд и давайте ваши отзывы.
Оригинал статьи Generating a Google Sitemap when you have thousands of resources
04-11-2013 приёмы MODx Revolution сниппеты sitemap SEO Виктор Матушевский
Василий Наумкин
05.11.2013 09:56И какие цифры?
pdoResources выводит почти 1955 страниц за полторы секунды http://d.pr/i/y4p6
Oleg Karyagin
05.11.2013 23:05Да, интересны цифры