[英]How to speed up MySQL query? Loading data from 3 tables
I have 3 tables. 我有3张桌子。 First: "atributy" Second: "atributy_value" Third: "produkty" 第一:“属性”第二:“属性值”第三:“产品”
I have this query first: 我首先有这个查询:
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
And my second query is this: 我的第二个查询是这样的:
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
Help me please make from this 2 query's 1 one better. 请帮我从这个2查询的1更好。 Reason: too long loading my web e-shop. 原因:加载我的网上商店太长。
EDIT: 编辑:
$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()
EDIT 2: 编辑2:
My table structure 我的表结构
produkty: http://i.imgur.com/J4Kz2CE.png
atributy_value: http://i.imgur.com/nX1uRph.png
atributy: http://i.imgur.com/mlCa3It.png
Indexes: 索引:
atributy: http://i.imgur.com/ppMEEOe.png
atributy_value: http://i.imgur.com/RHAeSiu.png
produkty: http://i.imgur.com/IUrgy9l.png
You can try Below Query: 您可以尝试以下查询:
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
In Inner Query Select Only Required Columns 在内部查询中,仅选择必需的列
Hope this works. 希望这行得通。
Two things are slow here. 这里有两件事很慢。
First - unnecessary outer / inner loop. 首先-不必要的外部/内部循环。 It should be possible to do this in a single SQL query, which will be a huge time saving. 应该可以在单个SQL查询中执行此操作,这将节省大量时间。 Without seeing the definitions of your tables, this is the best I can suggest : 在没有看到表定义的情况下,这是我可以建议的最好的方法:
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')
At least it's a starting point to test from. 至少这是一个可以测试的起点。
Second - Joining between the two tables using LIKE '%value%'. 第二-使用LIKE'%value%'在两个表之间进行联接。 Is there not an integer ID that links these two tables together? 是否没有将这两个表链接在一起的整数ID? Or at least, should the text be an exact match and you can remove the '%'s? 或者至少,文本是否应该完全匹配,您可以删除'%'?
EDIT (after adding table structure) : 编辑(添加表结构后):
You have two joins, the first from a nice indexed integer atributy_value.ValueCode to a non-indexed text field produkty.ATTRIBUTE_CODE, the second from a non indexed text field atributy.code to another non-indexed text field produkty.ATTRIBUTE_CODE. 您有两个联接,第一个联接从一个漂亮的索引整数atributy_value.ValueCode到一个非索引文本字段produkty.ATTRIBUTE_CODE,第二个联接从一个未索引的文本字段atributy.code到另一个非索引文本字段produkty.ATTRIBUTE_CODE。
It's not a good table structure, it would be easier and faster if every table had a unique integer ID to join on. 它不是一个好的表结构,如果每个表都有一个唯一的整数ID可以加入,它将变得更加容易和快捷。 But you might not have time to change this. 但是您可能没有时间更改此设置。
Can you just remove the %'s in your original queries and insist on an exact match between the columns? 您能只删除原始查询中的%并坚持列之间完全匹配吗? To keep it simple, you could just replace : 为简单起见,您可以替换为:
LIKE CONCAT('%', a.code, '%')
replace with 用。。。来代替
= a.code
and 和
LIKE CONCAT('%', atributy_value.ValueCode, '%')
replace with 用。。。来代替
= CONVERT( varchar(500), atributy_value.ValueCode)
This will make it faster. 这将使其更快。 If it's still not enough you could add indexes on Produkty.ATTRIBUTE_CODE and Produkty.ATTRIBUTE_VALUE and atributy.code. 如果仍然不够,可以在Produkty.ATTRIBUTE_CODE和Produkty.ATTRIBUTE_VALUE和atributy.code上添加索引。
1) Run an EXPLAIN on your queries and add indexes where necessary. 1)对您的查询运行EXPLAIN,并在必要时添加索引。 IMHO, these queries are not meant to run on production. 恕我直言,这些查询不是要在生产环境上运行。 However, I have made a suggestion below. 但是,我在下面提出了一个建议。
2) Let MySQL handle the query execution plan for you. 2)让MySQL为您处理查询执行计划。 Instead of mentioning a JOIN. 而不是提及加入。 Try this 尝试这个
$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) Also change the inner query to the following: 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 ")
I need more details on the table structures though 我需要有关表结构的更多详细信息
3) Run an EXPLAIN on the above query. 3)对上面的查询运行EXPLAIN。 If you have any missing indexes, please add them 如果缺少索引,请添加它们
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.