1

我有 3 张桌子。第一个:“属性”第二个:“属性值”第三个:“产品”

我首先有这个查询:

SELECT a.*, p.ATTRIBUTE_CODE, p.ATTRIBUTE_VALUE, p.KATEGORIA  
FROM atributy a JOIN produkty p ON p.ATTRIBUTE_CODE
LIKE CONCAT('%', a.code, '%')
AND
KATEGORIA IN ('$kategoria_sql') 
GROUP BY a.value

我的第二个查询是这样的:

SELECT * FROM atributy_value
INNER JOIN produkty 
ON produkty.ATTRIBUTE_VALUE LIKE CONCAT('%', atributy_value.ValueCode, '%')
AND AttributeCode = '$atribut_kod' 
AND KATEGORIA IN ('$kategoria_sql')
GROUP BY atributy_value.Value

请帮助我,让这 2 个查询的 1 个更好。原因:加载我的网上商店的时间过长。

编辑:

$query = mysql_query("
SELECT a.*, p.ATTRIBUTE_CODE, p.ATTRIBUTE_VALUE, p.KATEGORIA  
FROM atributy a JOIN produkty p ON p.ATTRIBUTE_CODE LIKE CONCAT('%', a.code, '%') 
AND KATEGORIA IN ('$kategoria_sql') 
GROUP BY a.value ");

while($result = mysql_fetch_object($query)){

$atribut_kod = $result->code;
$atribut_value = $result->value;
$nazov_produktu = $result->NAZOV;
$value1 = $result->ATTRIBUTE_VALUE;
$value1 = explode(" ", $value1);

$value1_count = count($value1);

echo "<div class=\"parametre_panel\">
<h3>".$atribut_value."</h3>
";

$url_kody .= "$atribut_kod,";

$hodnoty_qry = mysql_query("
SELECT * FROM atributy_value
INNER JOIN produkty ON produkty.ATTRIBUTE_VALUE LIKE CONCAT('%', atributy_value.ValueCode, '%')
AND AttributeCode = '$atribut_kod' 
AND KATEGORIA IN ('$kategoria_sql')  
GROUP BY atributy_value.Value ");

 while($hodnoty_res = mysql_fetch_object($hodnoty_qry)){
 $cislo_hodnoty = $hodnoty_res->ValueCode;
 echo "<input type=\"checkbox\" class=\"ZobrazParametrickeVyhladavanie\"   name=\"value[]\" id=\"$cislo_hodnoty\" value=\"".$atribut_kod."-".$cislo_hodnoty."\"><label for=\"$cislo_hodnoty\">".$hodnoty_res->Value."</label>
 ";

 $url_hodnoty .= "$cislo_hodnoty,";
} //second query while()
echo "</div>";
} //first query while()

编辑2:

我的表结构

produkty:       http://i.imgur.com/J4Kz2CE.png 
atributy_value: http://i.imgur.com/nX1uRph.png 
atributy:       http://i.imgur.com/mlCa3It.png

索引:

atributy:         http://i.imgur.com/ppMEEOe.png
atributy_value:   http://i.imgur.com/RHAeSiu.png
produkty:         http://i.imgur.com/IUrgy9l.png
4

3 回答 3

0

这里有两件事很慢。

首先 - 不必要的外/内循环。应该可以在单个 SQL 查询中执行此操作,这将节省大量时间。在没有看到你的表的定义的情况下,这是我能建议的最好的:

 SELECT a.*, p.*, av.*
 FROM produkty p 
 JOIN atributy a ON p.ATTRIBUTE_CODE LIKE CONCAT('%', a.code, '%') 
 JOIN atributy_value av ON p.ATTRIBUTE_VALUE LIKE CONCAT('%', av.ValueCode, '%') 
 WHERE 
 KATEGORIA IN ('$kategoria_sql') 

至少这是一个测试的起点。

第二 - 使用 LIKE '%value%' 在两个表之间连接。没有将这两个表链接在一起的整数 ID 吗?或者至少,文本是否应该完全匹配并且您可以删除“%”?

编辑(添加表结构后):

您有两个连接,第一个从漂亮的索引整数 atributy_value.ValueCode 到非索引文本字段 produkty.ATTRIBUTE_CODE,第二个从非索引文本字段 atributy.code 到另一个非索引文本字段 produkty.ATTRIBUTE_CODE。

这不是一个好的表结构,如果每个表都有一个唯一的整数 ID 来连接会更容易和更快。但你可能没有时间改变这一点。

您可以只删除原始查询中的 % 并坚持列之间的完全匹配吗?为了简单起见,您可以替换:

LIKE CONCAT('%', a.code, '%')

用。。。来代替

= a.code

LIKE CONCAT('%', atributy_value.ValueCode, '%') 

用。。。来代替

= CONVERT( varchar(500), atributy_value.ValueCode)

这将使它更快。如果还不够,您可以在 Produkty.ATTRIBUTE_CODE 和 Produkty.ATTRIBUTE_VALUE 和 atributy.code 上添加索引。

于 2013-07-29T12:54:42.377 回答
0

1) 对查询运行 EXPLAIN 并在必要时添加索引。恕我直言,这些查询并不意味着在生产中运行。但是,我在下面提出了一个建议。

2)让MySQL为你处理查询执行计划。而不是提到一个JOIN。尝试这个

$query = mysql_query("
                        SELECT a.*, p.ATTRIBUTE_CODE, p.ATTRIBUTE_VALUE, p.KATEGORIA 
                        FROM atributy a,produkty p 
                        WHERE p.ATTRIBUTE_CODE LIKE CONCAT('%', a.code, '%') 
                        AND KATEGORIA IN ('$kategoria_sql') 
                        GROUP BY a.value ");

2)还将内部查询更改为以下内容:

SELECT atributy_value.* FROM atributy_value AS atributy_value, produkty AS produkty  
WHERE 
produkty.ATTRIBUTE_VALUE LIKE CONCAT('%', atributy_value.ValueCode, '%')
AND atributy_value.AttributeCode = '$atribut_kod' 
AND produkty.KATEGORIA IN ('$kategoria_sql')  
GROUP BY atributy_value.Value ")

我需要更多关于表结构的细节

3) 对上述查询运行 EXPLAIN。如果您有任何缺失的索引,请添加它们

于 2013-07-29T13:05:43.613 回答
0

您可以尝试以下查询:

SELECT a.*, 
       p.ATTRIBUTE_CODE, 
       p.ATTRIBUTE_VALUE, 
       p.KATEGORIA  
  FROM atributy a 
  JOIN (SELECT * 
          FROM atributy_value
         INNER JOIN produkty 
            ON produkty.ATTRIBUTE_VALUE LIKE CONCAT('%', atributy_value.ValueCode, '%')
           AND AttributeCode = '$atribut_kod' 
           AND KATEGORIA IN ('$kategoria_sql')
         GROUP BY atributy_value.Value) p 
    ON p.ATTRIBUTE_CODE LIKE CONCAT('%', a.code, '%')
   AND KATEGORIA IN ('$kategoria_sql') 
 GROUP BY a.value

在内部查询中仅选择必需的列

希望这有效。

于 2013-07-29T08:45:42.187 回答