Как получить 200+ сотен страниц в Silverstripe в одном запросе?

Один из наших сайтов Silverstripe находится на виртуальном хостинге и имеет серьезные проблемы с производительностью. Кажется, что проблемы вызваны тем, что общий SQL-сервер ограничивает количество запросов, которые могут быть сделаны.

Страницы, которые работают медленнее, получают 200+ сотен страниц для размещения на карте Google:

$DirectoryItems = DirectoryItem::get()->where("\"Latitude\" IS NOT NULL AND \"Longitude\" IS NOT NULL ")->sort('Title ASC');
$MapItems = new ArrayList();
foreach ($DirectoryItems as $DirectoryItem) {
$MapItems->push(new ArrayData(array(
"Latitude" => $DirectoryItem->Latitude,
"Longitude" => $DirectoryItem->Longitude,
"MapMarkerURL" => $DirectoryItem->MapMarkerURL,
"Title" => addslashes($DirectoryItem->Title),
"Link" => $DirectoryItem->Link()
)));
}

Каждый из 200+ MapItems генерирует собственный SQL-запрос, который перегружает общий SQL-сервер.

Я начал пытаться получить ту же информацию с помощью одного запроса:

$DirectoryItems = DB::query('SELECT `DirectoryItem`.`Latitude`, `DirectoryItem`.`Longitude`, `DirectoryItem`.`MapMarkerURL`, `SiteTree_Live`.`Title`
FROM `DirectoryItem`, `SiteTree_Live`
WHERE `DirectoryItem`.`ID` = `SiteTree_Live`.`ID`
AND `DirectoryItem`.`Latitude` IS NOT NULL AND `DirectoryItem`.`Longitude` IS NOT NULL
ORDER BY `SiteTree_Live`.`Title`');

$MapItems = new ArrayList();
foreach ($DirectoryItems as $DirectoryItem) {
$MapItems->push(new ArrayData(array(
"Latitude" => $DirectoryItem['Latitude'],
"Longitude" => $DirectoryItem['Longitude'],
"MapMarkerURL" => $DirectoryItem['MapMarkerURL'],
"Title" => addslashes($DirectoryItem['Title']),
"Link" => ??????
)));
}

Но это падает, когда дело доходит до получения ссылки на DirectoryItem.

Я думал о добавлении ссылки как поля БД в DirectoryItem, но это начинает казаться излишне сложным для того, что должно быть простой операцией.

Каков наилучший способ получения информации для 200+ DirectoryItems в одном запросе?

0

Решение

Вы смотрели в кеширование? Если вы показываете одни и те же предметы на карте все время, вам не нужно нажимать на БД при каждом запросе.

Увидеть

Требуется огромная нагрузка на ваш сервер, если вы правильно кешируете.

Если у вас все еще есть проблемы при кэшировании, вы должны подумать о лучшем сервере.

1

Другие решения

Класс SiteTree имеет статическую функцию, которая используется в CMS для получения ссылки на определенный SiteTreeID. Так что вам просто нужно расширить SQL-запрос, чтобы получить идентификатор, и вы можете получить ссылку на любую страницу с помощью идентификатора, позвонив:

$link = SiteTree::link_shortcode_handler(array('id' => $id), false);

Изменить: wmk предложил другой и, вероятно, более перспективный способ использования:

$page = SiteTree::get()->byID($id);
if ($page instanceof SiteTree) $link = $page->Link();

Непроверенные; ЦСИ: http://api.silverstripe.org/master/class-SiteTree.html

0

По вопросам рекламы [email protected]