We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 30247
    • 74 Posts
    Очень стыдно, но незнание буржуйского заставляет задать эти вопросы:
    1. Есть ли нормально настраиваемый и удобно администрируемый сниппет "Голосания"
    В гугле был, нашел только мертвую тему http://www.modx-cms.ru/forum/comments.php?DiscussionID=73&page=1
    2. Есть папка содержащая n-штук документов, нужно из них выбрать 2-3 случайных. Я так понимаю, Ditto мне тут не помошник? Надо самому писать или есть готовые решения?
    3. При поиске ответов на предыдущие вопросы наткнулся на печальный факт:


    При росте числа документов резко падает производительность. Особенно заметно, когда документов становится действительно много — от 3000. Система начинает очень медленно работать вне зависимости от конфигурации сервера, на котором установлена, ресурсов, которые под нее выделены, и «толщины» интернет-канала. (С)http://anisand.com/CMF-MODx.html
    Мне конечно пока до 3000 далеко... с первым десятком бы поладить... Но хотелось бы знать: это дейстительно так? При каком кол-ве документов наступает заметное замедление работы?
      • 30247
      • 74 Posts
      Итак, видимо Fuzzy отдыхает, а кроме него никто не знает....
      Пытаюсь осознать сам. От варианта написать голосовалку самому, по причине неглубокого знания MODx отказался.
      Ход копания.
      Нашел 2 готовых варианта:
      EasyPoll(repo-2233)
      Polls Module (repo-528)
      Polls Module более легковесный (48КБ против 266КБ у Изи-пула) , с менее замороченной админкой. Но заточен он под некую древню версию MODx и соответственно пути внутри модуля и сниппета надо править. Для русфикации опять же надо править сниппет и модуль.
      EasyPoll достаточно заморочен, непонятно пока что делает эта куча кода. русификации нет. Для русификации надо отредактировать 2 lang файла.
      Оба модуля отредактированы и внедрены в MODx. Готовлюсь к играм с выводом.

      Add:
      Насколько я смог понять Polls Module для выбора выводимого голосования требует правки вызова. А это неудобно пользователю.
        • 30247
        • 74 Posts
        Итак, некоторые итоги:
        1.Пока мне больше понравился EasyPoll
        2. Решил написать свой сниппет. Тут несколько вариантов:
        2.1 использовать запрос к базе с "ORDER BY RAND() LIMIT $n" где $n количество необходимых вариантов. Тормознутость метода жуткая, ибо MySQL присваивает для всех строк виртуальный столбец, заполняемый случайными данными, затем сортирует таблицу по этому столбцу, и только потом выдает первые $n строк.
        2.2 Получать список id, средствами ПХП цеплять случайные строки и запросом цеплять их. Из минусов два запроса возвращающих объемы данных.
        2.3 Использовать SELECT count(*) AS count FROM modx_site_content WHERE parent = $start; затем сгенерить случайное число ($rand) в диапазоне записей ($count-$n) и сделать выборку из таблицы SELECT * FROM modx_site_content WHERE parent = $start LIMIT $rand, $n;

        Какой из вариантов предпочесть?

        3. Огромное спасио AKots’у за проведенные исследованияв области производительности! http://modxcms.com/forums/index.php/topic,38919.0.html
          • 785
          • 2,113 Posts
          Quote from: Tohin at Aug 24, 2009, 06:41 PM

          Eoae, iaeioi?ua eoiae:
          Кодировку в сообщении исправьте. И третий вариант однозначно не подходит - если документы удалялись, некоторых ID может просто не существовать. Вообще, вряд ли придумаете что-то оптимальней первого варианта.
            Создание сайтов на MODx, поддержка сайтов, поисковая оптимизация, программирование, копирайтинг
            Статьи о MODx, регулярно новые публикации
            • 30247
            • 74 Posts
            Quote from: AKots at Aug 25, 2009, 03:06 AM

            Кодировку в сообщении исправьте. И третий вариант однозначно не подходит - если документы удалялись, некоторых ID может просто не существовать. Вообще, вряд ли придумаете что-то оптимальней первого варианта.

            Кодировку вроде поправил.Прошу прощения. Опера почему то глюкает на этом форуме.
            А где, простите, в третьем варианте я использовал ID? Насколько я понимаю LIMIT считает строчки сам, без использования ID...
            Плюсы данного метода очевидны. в первом запросе используется служебная информация, и запрос выполняется практически мгновенно возвращая массив с единственным числовым элементом, второй запрос чуть тяжелее, но все равно лишь получает n строк таблицы и очень шустр.

            http://www.rldp.ru/mysql/mysqladm/glava05.htm
            5.2.4 Как MySQL оптимизирует предложение WHERE
            COUNT(*) на одиночной таблице без WHERE получен непосредственно из информации таблицы.
            Единственный минус в том, что получаются n-строк подряд, и если нужны совсем разные строки то лучше использовать второй вариант.
            Первый вариант однозначно неприемлем, попробуйте замерить время его выполнения на своей тестовой базе из 30 тыс. документов. Я думаю неприятно удивитесь. Я пробовал на "детской" базе из 60 документов:
            1.SELECT * FROM modx_site_content ORDER BY RAND() LIMIT 2 запрос занял 0.1185 сек
            2.SELECT count(*) AS count FROM modx_site_content запрос занял 0.0 сек.
            3. SELECT * FROM modx_site_content LIMIT 10 , 2 запрос занял 0.0072 сек.

            Экономия, даже на таком кол-ве документов заметная. А ведь в третьем запросе даже звездочка не нужна, можно прописать нужные поля.
              • 785
              • 2,113 Posts
              Попробовал на базе с 30000 записями. При этом первый вариант сделал без изменений, а последний вариант вызвал нужное количество раз (получая по одной записи в запросе), и получил случайные значения, расположенные не подряд. Следует заметить, что один запрос выполняется намного быстрее, но при нескольких запросах тратится больше времени, чем сумма времен отдельных запросов. Кстати, в последнем варианте время сильно зависит от номера записи – чем он больше, тем дольше выполняется запрос. Вот результаты:

              $tblsc= $modx->getFullTableName("site_content");
              $query = "SELECT id, pagetitle, longtitle, introtext, createdon FROM $tblsc ORDER BY RAND() LIMIT 2";
              $result= $modx->db->query($query);

              MySQL: 0.2335 s, 1 request(s)


              $tblsc= $modx->getFullTableName("site_content");
              $query = "SELECT count(*) AS count FROM $tblsc";
              $result= $modx->db->query($query);
              $param = $modx->db->getRow($result);
              for ($i = 1; $i <= 2; $i++) {
              $limit = rand (1, $param["count"])-1;
              $query = "SELECT id, pagetitle, longtitle, introtext, createdon FROM $tblsc LIMIT $limit, 1";
              $result= $modx->db->query($query);
              }

              MySQL: 0.1339 s, 3 request(s)


              Конечно, первый вариант дольше работает, но не смертельно. А вообще все зависит от задачи – для среднестатистического сайта в несколько сотен страниц и несколько сотен посетителей в день первый вариант вполне подходит. Вообще, я замечаю, что чаще нагрузка растет из-за выполнения множества команд PHP, а не из-за обращений к базе (конечно, если количество обращений в разумных пределах).
                Создание сайтов на MODx, поддержка сайтов, поисковая оптимизация, программирование, копирайтинг
                Статьи о MODx, регулярно новые публикации
                • 785
                • 2,113 Posts
                А вообще-то все имеющиеся ID в MODx хранятся в массиве $modx->documentListing, так что можно взять несколько случайных значений оттуда и одним запросом к базе взять нужную информацию.
                  Создание сайтов на MODx, поддержка сайтов, поисковая оптимизация, программирование, копирайтинг
                  Статьи о MODx, регулярно новые публикации
                  • 30247
                  • 74 Posts
                  Quote from: AKots at Aug 25, 2009, 09:32 AM

                  А вообще-то все имеющиеся ID в MODx хранятся в массиве $modx->documentListing, так что можно взять несколько случайных значений оттуда и одним запросом к базе взять нужную информацию.
                  Не катит... По parent выбрать нельзя.
                  Предложенный цикл тоже не катит:
                  1. При увеличени кол-ва выбираемых документов вырастет кол-во запросов.
                  2. Не исключены повторяющиеся варианты.

                  А если не секрет, как набивалась база из 30 тыс доков? Хочу у себя набить, посмотреть...
                    • 785
                    • 2,113 Posts
                    Quote from: Tohin at Aug 25, 2009, 11:17 AM

                    А если не секрет, как набивалась база из 30 тыс доков? Хочу у себя набить, посмотреть...
                    http://modxcms.com/forums/index.php/topic,38919.msg236340.html#msg236340
                    А по поводу вариантов - в итоге первый самый простой, а время в принципе допустимое.
                      Создание сайтов на MODx, поддержка сайтов, поисковая оптимизация, программирование, копирайтинг
                      Статьи о MODx, регулярно новые публикации
                      • 30247
                      • 74 Posts
                      Пока решил не заморачиваться:
                      <?php
                      $tblsc= $modx->getFullTableName("site_content");
                      $query = "SELECT id, pagetitle, introtext FROM $tblsc WHERE `parent`=$startid ORDER BY RAND() LIMIT 2";
                      $res= $modx->db->query($query);
                      $result="<div id=\"dictionary\">";
                      while($row = $modx->db->getRow( $res)) {
                      $result.="<p><a href=\"[~".$row["id"]."~]\">".$row["pagetitle"]."</a>—".$row["introtext"]."</p>" ;
                      }
                      $result.="</div>";
                      return $result;
                      ?>


                      В моем случае используется для вывода 2 случайных значений из словаря на все страницы, при клике на слово, представляется полное описание.