Оптимизация обработки страницы путем создания расширенного запроса SQL - PullRequest
0 голосов
/ 24 августа 2010

У меня есть этот странный код на сайте. Он получает все записи (order by pozycja), затем создает какой-то стек и ограничивает показанные записи до 10. Однако, если существует более 200 записей, это занимает слишком много времени, поскольку он обрабатывает всю таблицу вместо 10.

Используемые значения:

$int_ilosc_na_strone = 10;
$liczba_wierszy = 200;
Podzial_na_podstrony::get_limit_object($int_ilosc, $int_ilosc_na_strone) = 10;
$order = NULL;


public function produkty_kat($adres, $liczba_wierszy, $int_ilosc_na_strone) {
        require_once('lib/Podzial_na_podstrony.class.php');

        $rozloz = explode("/", $adres);
        $id = $rozloz[2];

        $order = $this->podaj_order($adres, 'kategorie');
        if (empty($order)) {
            $order = 'produkty.pozycja ASC';
        }
        if ($order=='price') {
            $order = "produkty.cena ASC";
        }
            $firstack = $this->database->pobierz("SELECT id FROM subkategorie WHERE kategorie_id = '$id' ORDER BY pozycja");
            foreach($firstack as $firstack)
            {
                $stack = $this->database->pobierz("SELECT id FROM sub_subkategorie WHERE subkategorie_id = '{$firstack['id']}' ORDER BY pozycja");
                foreach($stack as $stack)
                {
                    $prods[] = $this->database->pobierz("SELECT produkty.id FROM produkty, przyporzadkowania, stany_magazynowe, gk_grupy_produkty WHERE stany_magazynowe.produkty_id=produkty.id AND produkty.id=przyporzadkowania.produkty_id AND przyporzadkowania.sub_subkategorie_id={$stack['id']} AND produkty.widoczny='1' AND produkty.id = gk_grupy_produkty.id_produktu AND gk_grupy_produkty.id_grupy=$this->int_id_grupy AND gk_grupy_produkty.towar_widocznosc=1 GROUP BY produkty.pozycja ORDER BY $order");
                }
                $temp = array();
                foreach($prods as $o)
                {
                    foreach($o as $o)
                    {
                        $temp[] = $o;
                    }
                }
            }
            $temp2 = array();
            foreach($temp as $o)
            {
                $temp2[] = $o;
            }
            $wynik = $temp2;

            $int_ilosc = count($wynik);
            $this->int_liczba_wierszy = $int_ilosc;
            $obj_limit = null;
            if ($int_ilosc_na_strone > 0) {
                $obj_limit = Podzial_na_podstrony::get_limit_object($int_ilosc, $int_ilosc_na_strone);
            }
            $temp = array();
            $c = 0;
            foreach($wynik as $v)
            {
                if(is_object($obj_limit))
                {
                    if($c >= $obj_limit->min && $c < ($obj_limit->min + $obj_limit->max))
                    {
                        $temp[] = $v;
                    }
                    else if($c == ($obj_limit->min + $obj_limit->max))
                    {
                        break;
                    }
                }
                else
                {
                    $temp = $wynik;
                    break;
                }
                $c++;
            }
            $paged = $temp;
        return $paged;
    }

Это один большой беспорядок, и я думаю, что есть способ сделать его чище с помощью объединений SQL.

Спасибо за помощь!

Обновление:

Я хочу установить продукты в соответствующей категории / подкатегории / подкатегории (это функция для основных категорий) в определенном порядке. Он подобен стеку, потому что каждый продукт имеет только свою позицию в определенной подкатегории. Подкатегории имеют позиции в подкатегориях, подкатегории в категориях.

Так это выглядит так:

категория
- подкатегория 2 (позиция 1)
- подкатегория 6 (позиция 1)
--- продукт 11 (позиция 1)
--- продукт 7 (позиция 2)
- подкатегория 3 (позиция 2) --- продукт 3 (позиция 1)
--- продукт 2 (позиция 1)

Etc. Поле "pozycja" - это позиция, а число сразу после элемента - его идентификатор. Так что теперь я должен пройтись по элементам, затем установить стек и вернуть только часть.

Имя БД: panelepo_sweb

Ответы [ 2 ]

0 голосов
/ 24 августа 2010

Я попытался переписать запрос для вас. Попробуйте подписку.

Вы не указали, какую базу данных используете, поэтому некоторые синтаксис (например, TOP) могут отличаться.

SELECT top 100 p.id 
FROM subkategorie s
INNER JOIN sub_subkategorie ss on s.id = ss.subkategorie_id
INNER JOIN produkty p on p.id=pr.produkty_id 
INNER JOIN przyporzadkowania pr ss.id = pr.sub_subkategorie_id
INNER JOIN stany_magazynowe st on st.produkty_id = p.id 
INNER JOIN gk_grupy_produkty g on p.id = g.id_produktu 
WHERE s.kategorie_id = '$id'
    AND p.widoczny='1' 
    AND g.id_grupy=$this->int_id_grupy 
    AND g.towar_widocznosc=1 
GROUP BY p.pozycja 
ORDER BY $order    
0 голосов
/ 24 августа 2010

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

Подводя итог ....

$x=SELECT x1 FROM master_table WHERE...
loop
   $y=SELECT y1 FROM next_table WHERE some_foreign_key=$x['x1']....
   loop
      $z=SELECT z1 FROM another_table WHERE some_foreign_key=$y['y1']....

Да, это может быть более эффективным:

$x=SELECT master_table.x1,
      next_table.y1,
      another_table.z1
   FROM master_table, next_table, another_table
   WHERE master_table.x1=next_table.some_foreign_key
   AND next_table.y1=another_table.some_foreign_key
   ORDER BY x1, y1, z1;

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

Хотя это приведет к экспоненциальному сокращению количества обращений к базе данных и количества разборов, необходимых для обработки оператора, это может не дать значительного снижения общей производительности.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...