[Помогите] OcStore 1.5.4.1 Sitemap & скорость загрузки

Тема в разделе "OpenCart", создана пользователем hicenko, 1 авг 2013.

  1. hicenko

    hicenko

    Регистрация:
    24 янв 2013
    Сообщения:
    97
    Симпатии:
    17
    Нашел много тем, но конечного вердикта не нашел... :(

    Проблема №1:
    Перестал работать родной sitemap после добавления более 2400 позиций...
    Альтернативные способы (какие то кривые) можно как-то сделать, что бы справлялся родной генератор.

    Проблема №2
    Сайт начал грузится медленнее... Как можно ускорить, что-то не нашел методов для 1.5.4.1
     
  2. ingenerks

    ingenerks

    Регистрация:
    25 окт 2012
    Сообщения:
    254
    Симпатии:
    79
  3. hicenko

    hicenko

    Регистрация:
    24 янв 2013
    Сообщения:
    97
    Симпатии:
    17
    Спасибо за тему! Теперь найти бы "Optimize it! Быстрый google sitemap для большого количества товаров". Что-то все темы мертвые...
     
  4. hicenko

    hicenko

    Регистрация:
    24 янв 2013
    Сообщения:
    97
    Симпатии:
    17
    Как я понял проблема в том, что слишком большой запрос или слишком долгий запрос...
    Может возможно решить через 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;
     
  5. nix

    nix php, MySQL, UNIX, MikroTik ROSAPI

    Регистрация:
    16 янв 2013
    Сообщения:
    1.000
    Симпатии:
    889
    hicenko, Здесь не пеха виновата а тупой алгоритм выборки из БД
    менять надо алгоритм
     
    hicenko нравится это.
  6. hicenko

    hicenko

    Регистрация:
    24 янв 2013
    Сообщения:
    97
    Симпатии:
    17
    А как поменять, не сталкивались?
     
  7. nix

    nix php, MySQL, UNIX, MikroTik ROSAPI

    Регистрация:
    16 янв 2013
    Сообщения:
    1.000
    Симпатии:
    889
    смотрите в файл catalog/controller/feed/google_sitemap.php
    там все видно что да и как, а именно вызов функций из стандартных опенкартовсих моделей
    например вот первая $this->model_catalog_product->getProducts()
    и т.д....
    что не очень хорошо, так как алгоритм выборки не очень хорош...
     
  8. hicenko

    hicenko

    Регистрация:
    24 янв 2013
    Сообщения:
    97
    Симпатии:
    17
    Что-то не совсем понял, как исправить...
     
  9. alexsofdev

    alexsofdev

    Регистрация:
    13 янв 2013
    Сообщения:
    239
    Симпатии:
    46
  10. nix

    nix php, MySQL, UNIX, MikroTik ROSAPI

    Регистрация:
    16 янв 2013
    Сообщения:
    1.000
    Симпатии:
    889
    Как модно сказать что модуль решает проблему а потом еще что сначала надо его найти...
    Обоснуй чем он поможет, какой принціп быстродействия и как там улучшен алгоритм чтоб помочь ускорить карту сайта
     
  11. alexsofdev

    alexsofdev

    Регистрация:
    13 янв 2013
    Сообщения:
    239
    Симпатии:
    46
    > Как модно сказать что модуль решает проблему а потом еще что сначала надо его найти...
    Ты говоришь - есть проблема с алгоритмом выборки 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('&', '&amp;', str_replace('&amp;', '&', $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 тысяч. В таком случае генерится сразу несколько карт сайта, каждая из которых содержит свой сегмент товаров. Опенкарт, известное дело, не поддерживает такой фокус :smile:

    Ну что, достаточно полно? :smile:
     
  12. nix

    nix php, MySQL, UNIX, MikroTik ROSAPI

    Регистрация:
    16 янв 2013
    Сообщения:
    1.000
    Симпатии:
    889
    Например говорил а не вариант! Понимаю, у кадого свое понимания)

    Чего достаточно? Того что на пальцах и с бубном пропел как у тебя все хорошо?

    Какой ребенок такое мог написать где то на блоге и ты повторить.... :frown:
    Чем тебе nginx поможет? Пример, чем он быстрее чем apache например?
    Такие связк делаються на больших проектах, например таких как ВК и там другая постройка серверов, на статику свое железо и свой канал, а на динамику свое, тогда ето ефективно, а на одном железе да еще на ВПСке крутить такую связку - БЕССМЫСЛЕННО.
    к тому же, при чем тут ето вопше, если в многих людей хостинг включая ТС.

    Кто покупал и где тот человек что покупал, почему не порекомендовал етот модуль?

    И все? ты на самом деле считаеш что условия where status=1 ускорит выборку на много? или выборка суто нужных столбиков? )

    И разве етого достаточно, и етот кусок избавляет от тормозов при генерации? Смешно и не боле етого, чем он вопше отличаеться от стандартного....
    Покажи всю функцию getCategories тогда можно будет говорить....

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

    Хороший пример ето когда выборка будет не в самом цикле а потом еще одна .... а когда сначала выборка а потом средствами пхп разобрать все ето...
     
  13. skyinfo

    skyinfo

    Регистрация:
    18 дек 2013
    Сообщения:
    1
    Симпатии:
    0
    поправьте товарищи кодеры

    в 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;
        }
    по идеи примерно такая конструкция должна ускорить работу, но она не работает
     
  14. alexsofdev

    alexsofdev

    Регистрация:
    13 янв 2013
    Сообщения:
    239
    Симпатии:
    46
    Чтобы понимать о чем я говорю, нужно знать код опенкарта, а там происходит следующее:

    Вначале выполняется вооот такой запрос:
    Код:
    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/
     
    nix нравится это.
  15. nix

    nix php, MySQL, UNIX, MikroTik ROSAPI

    Регистрация:
    16 янв 2013
    Сообщения:
    1.000
    Симпатии:
    889
    Не знаю где ты етот кусок кода откопал но точно не из оригинала опенкарт, он явно меньше дерьма берет из БД
    ткни носов в файл где ты такое увидел в оксторе, я не пользуюсь ним.(выложы сюда)
     
    Lasted edited by : 21 янв 2014
  16. alexsofdev

    alexsofdev

    Регистрация:
    13 янв 2013
    Сообщения:
    239
    Симпатии:
    46
    Ну ты же умный человек, с руками из правильного места, ты знаешь во что транслируется эти вызовы

    PHP:
    $this->model_catalog_product->getProducts(); 
    $this->model_catalog_product->getProduct();
    Так почему бы тебе не скачать опенкарт ( даже не окстор ) и не глянуть лично?

    Вот тебе оригинальная функция getProduct()
    [​IMG]

    А вот тебе оригинальная функция getProducts()
    [​IMG]
    которая не влезла в один экран
    [​IMG]
     
  17. nix

    nix php, MySQL, UNIX, MikroTik ROSAPI

    Регистрация:
    16 янв 2013
    Сообщения:
    1.000
    Симпатии:
    889
    alexsofdev, точно, не заметил в модели, приношу извинения
    PHP:
    foreach ($query->rows as $result) {
                    
    $product_data[$result['product_id']] = $this->getProduct($result['product_id']);
                }
     
    alexsofdev нравится это.
  18. Volsky

    Volsky

    Регистрация:
    22 ноя 2012
    Сообщения:
    192
    Симпатии:
    10
    есть vqmod модуль?