Нашел много тем, но конечного вердикта не нашел... :( Проблема №1: Перестал работать родной sitemap после добавления более 2400 позиций... Альтернативные способы (какие то кривые) можно как-то сделать, что бы справлялся родной генератор. Проблема №2 Сайт начал грузится медленнее... Как можно ускорить, что-то не нашел методов для 1.5.4.1
Спасибо за тему! Теперь найти бы "Optimize it! Быстрый google sitemap для большого количества товаров". Что-то все темы мертвые...
Как я понял проблема в том, что слишком большой запрос или слишком долгий запрос... Может возможно решить через php.ini? Код: magic_quotes_gpc = Off; register_globals = Off; default_charset = UTF-8; memory_limit = 192M; max_execution_time = 24000; upload_max_filesize = 999M; safe_mode = Off; mysql.connect_timeout = 20; session.use_cookies = On; session.use_trans_sid = Off; session.gc_maxlifetime = 12000000; allow_url_fopen = on; ;display_errors = 1; ;error_reporting = E_ALL;
смотрите в файл catalog/controller/feed/google_sitemap.php там все видно что да и как, а именно вызов функций из стандартных опенкартовсих моделей например вот первая $this->model_catalog_product->getProducts() и т.д.... что не очень хорошо, так как алгоритм выборки не очень хорош...
Исправить можно вот так - http://opencartsoftware.blogspot.com/2013/07/opencart-sitemap-pro.html Осталось найти этот модуль в халявном доступе
Как модно сказать что модуль решает проблему а потом еще что сначала надо его найти... Обоснуй чем он поможет, какой принціп быстродействия и как там улучшен алгоритм чтоб помочь ускорить карту сайта
> Как модно сказать что модуль решает проблему а потом еще что сначала надо его найти... Ты говоришь - есть проблема с алгоритмом выборки getProducts. Я говорю что ее подметил и решил другой человек в своем модуле, о чем он явно отписывает у себя на страничке. Вроде все просто, нет? Лично я модуль не покупал, потому как у меня генерация карты сайта на холодную ( предварительно почистить все кешы ) длится всего 15 секунд. Так что это не есть проблема. Но если обсуждать как именно можно решить этот вопрос теоретически, то ... то я бы создал отдельную функцию для выборки продуктов под сайтмап, которая дергала бы вот такой sql-запрос: Код: "select date_added, date_modified, product_id from product where status=1" Полагаю автор именно так и сделал. Если же говорить о проблемах генерации карты сайта, то их целых 4. 1. Тормоза при выборе списка товаров 2. Тормоза при генерации xml-блока с товарами ( из-за ЧПУ ) 3. Время отдачи сервером 4. Отсутствие партиционирования. Пункт 1 мы уже обсудили выше, у меня он отнимает 6 секунд Пункт 2 у меня отнимает 9 секунд и за него отвечает вот этот кусочек кода: Код: foreach ($products as $product) { $output .= '<url>'; $output .= '<loc>' . str_replace('&', '&', str_replace('&', '&', $this->url->link('product/product', 'product_id=' . $product['product_id']))) . '</loc>'; $output .= '<lastmod>' . substr(max($product['date_added'], $product['date_modified']), 0, 10) . '</lastmod>'; $output .= '<changefreq>weekly</changefreq>'; $output .= '<priority>1.0</priority>'; $output .= '</url>'; } Фактически вызов $this->url->link будет приводить к дополнительным выборкам из базы данных, а точнее из url_alias, поскольку нужных данных под рукой не найдется. Тут тоже не все так грустно, пожалуй можно было бы сделать еще одну выборку из url_alias, сразу построив нужные кеши, чтобы не лазить за каждым продуктом отдельно. Пункт 3. Собственно выкачивание сгенерированных данных поисковиком - очень сильно зависит от канала и размера файла. У меня, какого-то икса, скачивание выполняется целых 15 секунд. Но ни гугл ни яндекс пока не протестовали, поэтому не заморачивался. Если кому-то прям печет, то могу предложить решение в лоб - сделайте генерацию кроном, а на запросы поисковика или браузера отдавайте уже сгенеренный файл. Плюсы очевидны - затраты на генерацию отсутствуют. Из неочевидных плюсов - выдачу можно засунуть под nginx и тогда можно отдать не просто быстро, но и очень быстро, включив сжатие!!! Пункт 4. Краем уха слышал, но настаивать не буду, что поисковики не любят карты сайта размером больше 10 мегабайт или с количеством элементов более 50 тысяч. В таком случае генерится сразу несколько карт сайта, каждая из которых содержит свой сегмент товаров. Опенкарт, известное дело, не поддерживает такой фокус Ну что, достаточно полно?
Например говорил а не вариант! Понимаю, у кадого свое понимания) Чего достаточно? Того что на пальцах и с бубном пропел как у тебя все хорошо? Какой ребенок такое мог написать где то на блоге и ты повторить.... Чем тебе nginx поможет? Пример, чем он быстрее чем apache например? Такие связк делаються на больших проектах, например таких как ВК и там другая постройка серверов, на статику свое железо и свой канал, а на динамику свое, тогда ето ефективно, а на одном железе да еще на ВПСке крутить такую связку - БЕССМЫСЛЕННО. к тому же, при чем тут ето вопше, если в многих людей хостинг включая ТС. Кто покупал и где тот человек что покупал, почему не порекомендовал етот модуль? И все? ты на самом деле считаеш что условия where status=1 ускорит выборку на много? или выборка суто нужных столбиков? ) И разве етого достаточно, и етот кусок избавляет от тормозов при генерации? Смешно и не боле етого, чем он вопше отличаеться от стандартного.... Покажи всю функцию getCategories тогда можно будет говорить.... Пост выше ничего не обясняет кроме как говорит что у меня так и все должно быть так, и у автора так но я не знаю так ли ето так как не покупал, и надо сделать наверное ето еще так как ето лучше..... Короче бред. Хороший пример ето когда выборка будет не в самом цикле а потом еще одна .... а когда сначала выборка а потом средствами пхп разобрать все ето...
поправьте товарищи кодеры в catalog/model/catalog/product.php Код: public function getProductSitemap($data = array()) { $sql = "SELECT date_added, date_modified, product_id FROM av_product WHERE status = 1"; $query = $this->db->query($sql); return $query->rows; } по идеи примерно такая конструкция должна ускорить работу, но она не работает
Чтобы понимать о чем я говорю, нужно знать код опенкарта, а там происходит следующее: Вначале выполняется вооот такой запрос: Код: SELECT p.product_id, (SELECT AVG(rating) AS total FROM review r1 WHERE r1.product_id = p.product_id AND r1.status = '1' GROUP BY r1.product_id) AS rating FROM product p LEFT JOIN product_description pd ON (p.product_id = pd.product_id) LEFT JOIN product_to_store p2s ON (p.product_id = p2s.product_id) WHERE pd.language_id = '1' AND p.status = '1' AND p.date_available <= NOW() AND p2s.store_id = '0' GROUP BY p.product_id ORDER BY p.sort_order ASC, LCASE(pd.name) ASC; Тут достаточно глянуть на джойны с сортировками, чтобы понять что на несчастном впс уже этот запрос является корнем проблемы. Но на самом деле это половина проблемы, поскольку этот запрос возвращает не требуемые данные, а айди продуктов и затем заботливо в цикле выполняет еще и такой запрос: Код: SELECT DISTINCT *, pd.name AS name, p.image, m.name AS manufacturer, (SELECT price FROM product_discount pd2 WHERE pd2.product_id = p.product_id AND pd2.customer_group_id = '0' AND pd2.quantity = '1' AND ((pd2.date_start = '0000-00-00' OR pd2.date_start < NOW()) AND (pd2.date_end = '0000-00-00' OR pd2.date_end > NOW())) ORDER BY pd2.priority ASC, pd2.price ASC LIMIT 1) AS discount, (SELECT price FROM product_special ps WHERE ps.product_id = p.product_id AND ps.customer_group_id = '0' AND ((ps.date_start = '0000-00-00' OR ps.date_start < NOW()) AND (ps.date_end = '0000-00-00' OR ps.date_end > NOW())) ORDER BY ps.priority ASC, ps.price ASC LIMIT 1) AS special, (SELECT points FROM product_reward pr WHERE pr.product_id = p.product_id AND customer_group_id = '0') AS reward, (SELECT ss.name FROM stock_status ss WHERE ss.stock_status_id = p.stock_status_id AND ss.language_id = '1') AS stock_status, (SELECT wcd.unit FROM weight_class_description wcd WHERE p.weight_class_id = wcd.weight_class_id AND wcd.language_id = '1') AS weight_class, (SELECT lcd.unit FROM length_class_description lcd WHERE p.length_class_id = lcd.length_class_id AND lcd.language_id = '1') AS length_class, (SELECT AVG(rating) AS total FROM review r1 WHERE r1.product_id = p.product_id AND r1.status = '1' GROUP BY r1.product_id) AS rating, (SELECT COUNT(*) AS total FROM review r2 WHERE r2.product_id = p.product_id AND r2.status = '1' GROUP BY r2.product_id) AS reviews, p.sort_order FROM product p LEFT JOIN product_description pd ON (p.product_id = pd.product_id) LEFT JOIN product_to_store p2s ON (p.product_id = p2s.product_id) LEFT JOIN manufacturer m ON (p.manufacturer_id = m.manufacturer_id) WHERE p.product_id = '1' AND pd.language_id = '1' AND p.status = '1' AND p.date_available <= NOW() AND p2s.store_id = '0'; На моем Время исполнения первого запроса - 120мс на моем вДс. Время исполнения второго запроса - 12мс. Теперь берем 20,000 товаров... Теперь берем vps... Я проверил на тупом vps - гугл сайтмап через 10 секунд вылетает от нехватки памяти. Рабочий модуль и демо ролик можно посмотреть тут - http://opencartforum.ru/files/file/1606-soforp-шустрый-sitemap/
Не знаю где ты етот кусок кода откопал но точно не из оригинала опенкарт, он явно меньше дерьма берет из БД ткни носов в файл где ты такое увидел в оксторе, я не пользуюсь ним.(выложы сюда)
Ну ты же умный человек, с руками из правильного места, ты знаешь во что транслируется эти вызовы PHP: $this->model_catalog_product->getProducts(); $this->model_catalog_product->getProduct(); Так почему бы тебе не скачать опенкарт ( даже не окстор ) и не глянуть лично? Вот тебе оригинальная функция getProduct() А вот тебе оригинальная функция getProducts() которая не влезла в один экран
alexsofdev, точно, не заметил в модели, приношу извинения PHP: foreach ($query->rows as $result) { $product_data[$result['product_id']] = $this->getProduct($result['product_id']); }