我有3张桌子。 第一:“atributy” 第二:“atributy_value” 第三:“产品”
我先得到这个问题:
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
答案 0 :(得分: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
在内部查询中仅选择必需的列
希望这有效。
答案 1 :(得分: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上添加索引。
答案 2 :(得分: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。如果您有任何缺失的索引,请添加它们