2010-08-24 60 views
0

我在网站上有这个奇怪的代码。它获取所有记录(由pozycja命令),然后创建某种堆栈并将显示的记录限制为10.但是,如果有超过200条记录,则需要太长时间,因为它正在处理整个表格,而不是10个。通过创建高级SQL查询优化页面处理

值使用:

$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连接。

感谢您的帮助!

更新:

我想设置产品在相应类别/子/ subsubcategory(这是主要类别的功能)在特定的顺序。它就像堆栈一样,因为每个产品在特定的子类别中只有它的位置。子类别在子类别中具有位置,在类别中具有子类别。

所以看起来:

类别
- 子类别2(位置1)
- subsubcategory 6(位置1)
---产物11(位置1)
---产品7(位置2)
- subsubcategory 3(位置2) ---产物3(位置1)
---产物2(位置1)

等等“pozycja”字段是位置,元素之后的数字是它的id。所以现在我必须循环遍历元素,然后设置堆栈并仅返回一块。

DB名称:panelepo_sweb

+0

将非常有用,如果您描述您的代码中使用的每个表,并且您尝试实现。 – 2010-08-24 13:34:47

回答

0

是的,它是一个大混乱。如果你清理了一下并且只向我们展示了导致问题的部分,这将会很有帮助。

总结....

$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; 

注意,如果你需要组一起记录取决于它们的层次顺序时,才需要 - 您可以通过将获取的值与前一次迭代中的状态变量进行比较来在单个循环中处理层次结构。

虽然这会减少指向数据库的往返次数和处理语句所需的解析数量,但它可能不会大幅降低整体性能。

+0

可能值得在该查询的优化版本中的SELECT中指定TOP 10(或者等效,如果不是SQLServer),并且废除所有除前10行之外的所有离散逻辑... – 2010-08-24 13:56:29

+0

这不是这样的虽然:(好吧,我会尝试 – Misiur 2010-08-30 17:15:39

0

我采取了刺探重写查询为你。给follownig一个尝试。

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