Тут хочу дать два простых безапелляционных совета. Они просты как мычание:
- Не использовать wordpress, потому что это дерьмо работает кое как на объемах до 10к записей. Это блог. Любительская ху*ня никуда не годная под бизнес. Тот у кого хватило ума создавать на ней магазины, серьезные новостники и прочее — поздравляю — вы критический дебил. Вы потратите больше в результате, получив худшее.
- Не юзать карты сайта или юзать их только на начальном этапе.
Посмотрел на запросы для карт от aiseo и ужаснулся:
Плятттть… это тихий ужас… Как ещё и совести хватает что то продавать в своём плагине, какие то там подписки, услуги… уберите ссылку Pricing со своего сайта, долбоёбы вы блядь(это к создателям aiseo плагина), вы не программисты, вы дешевые, очень скудные аматоры. Тьфу на вас блядь!
UPD: из-за этих дебилов пришлось «на коленке» слепить реализацию. Дебилы(это к создателям aiseo плагина), вот это решение-реализация динамических карт летает на 100млн записей, а ваша реализация, это не что иное как параша чистой воды, которая начинает буксовать с 10к записей. Без возможности что либо исправить. Какие count? Какие join? Вы шо дебилы реально? Вы сами то юзали свою *уйню что пишете и продавать ещё совести хватает?
Вот это в index.php поверх всего, и будет вам карта сайта, работающая на любом количестве записей мгновенно отдавая индексный сайтмеп и любую его часть:
const SITEMAP_LIMIT = 1000;
$request = strtok($_SERVER['REQUEST_URI'], '?');
if (strpos($request, '.xml') !== false && preg_match('#^/(sitemap|post-sitemap([\d]+))\.xml$#', $request, $matches)) {
$dbh = new PDO("mysql:dbname=db_name;host=localhost;port=3306;charset=utf8", 'db_user', 'db_password', [PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_OBJ]);
list($min_id, $max_id) = $dbh->query("SELECT MIN(ID), MAX(ID) FROM wp_posts")->fetch(\PDO::FETCH_NUM);
$range_arr = $max_id - $min_id >= SITEMAP_LIMIT ? range($min_id, $max_id, SITEMAP_LIMIT) : [$min_id];
if ($matches[1] == 'sitemap') {
header("Content-Type: text/xml; charset=utf-8");
$xml = new \XMLWriter();
$xml->openMemory();
$xml->startDocument('1.0', 'UTF-8');
$xml->startElement("sitemapindex");
$xml->writeAttribute('xmlns', 'http://www.sitemaps.org/schemas/sitemap/0.9');
foreach ($range_arr as $key => $item) {
$xml->startElement("sitemap");
$xml->writeElement("loc", 'https://' . $_SERVER['HTTP_HOST'] . '/post-sitemap' . ($key + 1) . '.xml');
$xml->endElement();
}
$xml->endElement();
$out = $xml->outputMemory();
echo $out;
exit;
} elseif (!empty($matches[2]) && !empty($range_arr[$matches[2] - 1])) {
$id = $range_arr[$matches[2] - 1];
$sth = $dbh->query("SELECT * FROM wp_posts WHERE ID BETWEEN $id AND " . ($id + SITEMAP_LIMIT - 1));
$posts = $sth->fetchAll();
header("Content-Type: text/xml; charset=utf-8");
$xml = new \XMLWriter();
$xml->openMemory();
$xml->startDocument('1.0', 'UTF-8');
$xml->startElement("urlset");
$xml->writeAttribute('xmlns', 'http://www.sitemaps.org/schemas/sitemap/0.9');
foreach ($posts as $row) {
if ($row->post_status != 'publish' || $row->post_type != 'post') continue;
$xml->startElement("url");
$xml->writeElement("loc", str_replace('http://', 'https://', $row->guid));
$xml->writeElement("lastmod", date('Y-m-d', strtotime($row->post_modified)));
$xml->endElement();
}
$xml->endElement();
$out = $xml->outputMemory();
echo $out;
exit;
}
}