Проблема функционирования каталога на больших объемах

(1/7) > >>

KVT:
Сегодня обнаружилась проблема функционирования каталога Zoo на объемах более 1000 позиций (сейчас в каталоге более 6 тыс. позиций, а будет около 18 тыс.). Если коротко, то на больших объемах он начинает усиленно грузить сервер и возрастает нагрузка на сервер БД. В результате тестирования выяснилось, какой из запросов является виновником.

В классе ItemModelItems есть метод getTotal, который вычисляет количество записей просто выбирая все записи из БД, при чем с JOIN'ами и группировками. А потом смотрит сколько выбрано, вместо того, чтобы правильно построить запрос на вычисление количества записей.

Исправленный вариант этого метода должен выглядеть так:
Код:

 /**
   * Method to get the total number of items
   *
   * @access public
   * @return integer
   */
  function getTotal() {
    if (empty($this->_total)) {
      $db          =& JFactory::getDBO();
      $table       =& $this->getTable($this->_table);
      $where       =  $this->_buildContentWhere();

      // parse catalog/category
      if (strpos($this->getState('filter_category_id'), ':')) {
        list($catalog_id, $category_id) = explode(':', $this->getState('filter_category_id'), 2);
      } else {
        list($catalog_id, $category_id) = array(0, 0);
      }
      
      $query = 'SELECT count(*) FROM '.$table->getTableName().' AS a'
        .(($catalog_id > 0 || $category_id > 0)? ' JOIN '.ZOO_TABLE_CATEGORY_ITEM.' AS ci ON a.id = ci.item_id' : '')
        .$where;

      $db->setQuery($query);
      $this->_total = $db->loadResult();
    }
    
    return $this->_total;
  }


Сервер передумал загружать мои файлы, сославшись на нехватку места, т.ч. оставляю ссылку для скачивания хака: http://www.cms-service.ru/file-11.html

KVT:
Выяснилось еще одно узкое место: при выборке записей из базы для отображения на фронтальной части сайта каталог выбирает все записи заданного каталога/категории и потом делает вырезку нужного количества из массива результатов. При больших объемах PHP расходует всю доступную память и, как следствие - фатальная ошибка. Кроме того, это приводит к трениям с хостером при использовании виртуального хостинга.

Исправляется следующим образом:

в класс TableItem (файл /administrator/components/com_zoo/tables/item.php) добавляется метод getCountFromCategory
Код:

function getCountFromCategory($catalog_id, $category_id, $published = false, $access_id = false){

$date =& JFactory::getDate();
$now  = $this->_db->Quote($date->toMySQL());
$null = $this->_db->Quote($this->_db->getNullDate());

$query = "SELECT count(*)"
." FROM ".$this->getTableName()." AS a"
." LEFT JOIN ".ZOO_TABLE_CATEGORY_ITEM." AS b ON a.id = b.item_id"
." WHERE b.catalog_id = ".(int) $catalog_id
." AND b.category_id ".(is_array($category_id)? " IN (".implode(",", $category_id).")" : " = ".(int) $category_id)
.($published == true ? " AND a.state = 1" : "")
.($access_id !== false ? " AND a.access <= ".(int) $access_id : "")
." AND (a.publish_up = ".$null." OR a.publish_up <= ".$now.")"
." AND (a.publish_down = ".$null." OR a.publish_down >= ".$now.")"
;

$this->_db->setQuery($query);
return $this->_db->loadResult();
}


в классе ZooModelCategory (файл /components/com_zoo/models/category.php) метод getItems должен выглядеть так:
Код:

function getItems() {
if (empty($this->items)) {

// set order
$orders = array('date' => 'a.created ASC', 'rdate' => 'a.created DESC',
'alpha' => 'a.name ASC', 'ralpha' => 'a.name DESC',
'hits' => 'a.hits DESC', 'rhits' => 'a.hits ASC',
'ordering' => 'a.ordering ASC', 'rordering' => 'a.ordering DESC');
$order = isset($orders[$this->item_order])? $orders[$this->item_order] : '';

// get items
$table =& JTable::getInstance('item', 'Table');
$table->setCache($this->cache);
$itemsCount = $table->getCountFromCategory($this->catalog_id, $this->category_id, true, $this->user->get('aid', 0));

// set pagination
$this->pagination = new YPagination('page', $itemsCount, $this->page, $this->items_per_page);
$this->pagination->setShowAll($this->items_per_page == 0);

// slice out items
if ($this->pagination->getShowAll()) {
$this->items = $table->getFromCategory($this->catalog_id, $this->category_id, true, $this->user->get('aid', 0), $order, 0, $itemsCount);
} else {
$this->items = $table->getFromCategory($this->catalog_id, $this->category_id, true, $this->user->get('aid', 0), $order, $this->pagination->limitStart(), $this->items_per_page);
}
}

return $this->items;
}

snowindy:
Как сейчас ведет себя производительность? С Вашими модификациями ушли все проблемы, или все равно медленновато?

KVT:
Проблемы ушли, что не может не радовать :-)

CTPAHHuK:
А можно попросить приаттачить исправленные файлики. (Zoo 1.07)

Навигация

[0] Главная страница сообщений

[#] Следующая страница