Php 通过创建高级SQL查询优化页面处理

Php 通过创建高级SQL查询优化页面处理,php,sql,time,Php,Sql,Time,我在网站上有一个奇怪的代码。它获取所有记录(按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;

我在网站上有一个奇怪的代码。它获取所有记录(按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;
    }
$int\u ilosc\u na\u strone=10;
$liczba_wierszy=200;
Podzial_na_podstrony::get_limit_object($int_ilosc,$int_ilosc_na_strone)=10;
$order=NULL;
公共功能产品(adres、liczba、wierszy、int、ilosc、na、strone){
require_once('lib/Podzial_na_podstrony.class.php');
$rozloz=爆炸(“/”,$adres);
$id=$rozloz[2];
$order=$this->podaj_order($adres,'kategorie');
if(空($order)){
$order='produkty.pozycja ASC';
}
如果($order=='price'){
$order=“produkty.cena ASC”;
}
$firstack=$this->database->pobierz(“从子kategorie中选择id,其中kategorie_id='$id'按pozycja排序”);
foreach($firstack作为$firstack)
{
$stack=$this->database->pobierz(“从sub_subkategorie中选择id,其中subkategorie_id='{$firstack['id']}'按pozycja排序”);
foreach($stack as$stack)
{
$prods[]=$this->database->pobierz(“从produkty、przyporzadkowania、stany_magazynowe、gk_grupy_produkty中选择produkty.id,其中stany_magazynowe.produkty_id=produkty.id=przyporzadkowania.produkty_id和przyporzadkowania.subkategorie.id={$stack['id']和produkty.widoczny='1'和produkty.id=gk_grupy_produkty.id_produktu和gk_grupy_produkty.id_grupy=$this->int_id_grupy和gk_grupy_produkty.towar_widocznosc=1组BY produkty.pozycja ORDER BY$ORDER”);
}
$temp=array();
foreach($prods作为$o)
{
foreach($o作为$o)
{
$temp[]=$o;
}
}
}
$temp2=array();
foreach($temp作为$o)
{
$temp2[]=$o;
}
$wynik=$temp2;
$int_ilosc=计数($wynik);
$this->int_liczba_wierszy=$int_ilosc;
$obj_limit=null;
如果($int\u ilosc\u na\u strone>0){
$obj_limit=Podzial_na_podstrony::get_limit_object($int_ilosc,$int_ilosc_na_strone);
}
$temp=array();
$c=0;
foreach($wynik作为$v)
{
如果(是对象($obj_限制))
{
如果($c>=$obj_limit->min&&$c<($obj_limit->min+$obj_limit->max))
{
$temp[]=$v;
}
否则如果($c==($obj\U limit->min+$obj\U limit->max))
{
打破
}
}
其他的
{
$temp=$wynik;
打破
}
$c++;
}
$paged=$temp;
返回$paged;
}
这是一个大混乱,我认为有办法通过SQL连接使它更干净

谢谢你的帮助

更新:

我想按特定顺序设置相应类别/子类别/子类别(这是主类别的函数)中的产品。它是堆栈式的,因为每个产品在特定的子类别中只有其位置。子类别在子类别中有位置,子类别在类别中有位置

所以它看起来像:

类别
-子类别2(位置1)
--子类别6(位置1)
---产品11(职位1)
---产品7(职位2)
--次级类别3(职位2) ---产品3(职位1)
---产品2(职位1)

等等,“pozycja”字段是位置,元素后面的数字是它的id。所以现在我必须循环元素,然后设置堆栈并只返回片段


DB名称:panelepo_sweb

是的,真是一团糟。如果您稍微清理一下,只向我们展示导致问题的部件,那会很有帮助

总而言之

$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;
注意:只有当您需要根据记录的层次结构将记录分组时,才需要排序,并且您可以通过将获取的值与上一次迭代中的状态变量进行比较,在单个循环中处理该层次结构


尽管这将成倍地减少到数据库的往返次数和处理语句所需的解析次数,但可能不会大幅降低总体性能。

我尝试过为您重写查询。试试下面的方法

您没有指定要使用的数据库,因此某些语法(例如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    

如果您描述代码中使用的每个表,并尝试实现这些表,将非常有帮助。在优化版本的查询中指定SELECT上的前10个表(或等效表,如果不是SQLServer的话),并删除除前10行之外的所有离散逻辑,可能值得一试