以下是查询。此查询如何优化?
SELECT representative.rep_name AS RNAME,
SUM(areawise_temp.quantity*product.ptr) AS TOTPTR,
SUM(areawise_temp.quantity*product.pts) AS TOTPTS
FROM areawise_temp,
product,
representative
WHERE (areawise_temp.bill_date BETWEEN '2015/04/01' AND '2015/04/30')
AND areawise_temp.our_cust_id <> ''
AND areawise_temp.our_product_id <> ''
AND areawise_temp.Pincode IN
(
SELECT pincode_list.pincode
FROM pincode_list
WHERE pincode_list.pin_id IN
(
SELECT rep_area.pin_id
FROM rep_area
WHERE rep_id IN
(
SELECT id
FROM representative
)
)
GROUP BY pincode_list.pincode
)
AND areawise_temp.our_product_id = product.id
答案 0 :(得分:0)
编码模式IN ( SELECT ... )
的优化程度非常低。将其更改为JOIN
。
例如,最里面的部分可以是
SELECT ra.pin_id
FROM rep_area AS ra
JOIN representative AS r ON r.id = ra.rep_id
还要确保您拥有必要的索引。让我们看SHOW CREATE TABLE
来帮助你。对于上面的代码段,representative
可能有PRIMARY KEY(id)
?
答案 1 :(得分:0)
在“优化”之前,请确保它返回正确的结果。对代表的交叉连接操作看起来很奇怪。没有GROUP BY,因此产品和数量的“总计”实际上乘以representative
中的行数。 (这样做并没有效果,但结果却很奇怪
我们将质疑它。)
已经是2015年了。过去的时间抛弃了用于连接操作的旧式逗号语法。使用JOIN
关键字。并将连接谓词从WHERE
子句重定位到ON
子句。
当我们省略连接谓词时,为了帮助未来的读者,我们希望包含CROSS
关键字作为对有意省略连接谓词的指示。
另外,我会避免使用IN (subquery)
,并使用连接操作来获得相同的结果。
所以,首先,我会重新编写查询:
SELECT r.rep_name AS RNAME -- not deterministic, no GROUP BY
, SUM(t.quantity*p.ptr) AS TOTPTR
, SUM(t.quantity*p.pts) AS TOTPTS
FROM areawise_temp t
JOIN product p
ON p.id = t.our_product_id
JOIN ( SELECT l.pincode
FROM pincode_list l
JOIN rep_area a
ON a.pin_id = l.pin_id
JOIN representative e
ON e.id = a.rep_id
GROUP BY l.pincode
) c
ON c.pincode = t.pincode
CROSS
JOIN representative r
WHERE t.bill_date BETWEEN '2015/04/01' AND '2015/04/30'
AND t.our_cust_id <> ''
AND t.our_product_id <> ''
这应该等同于原始查询,并返回相同的结果(可能具有不同的RNAME值,因为这是不确定的。)
不是belabor已经做出的一点,但是交叉加入representative
看起来很奇怪。我强烈怀疑原始查询是而不是返回您实际想要返回的结果。
就性能而言,我们的下一个问题是our_cust_id
和our_product_id
列的数据类型...如果这些是数字,则与空字符串的不等式比较是奇数。)数据类型bill_date
的{{1}},如果那是DATE
,那么我们真的希望文字有破折号分隔符,而不是斜线。 (我认为MySQL会很好地识别斜线,但我们更习惯于使用破折号查看日期文字,我们肯定知道它有用。)
基本上,我们想要了解我们强制MySQL执行的任何隐式数据类型转换,因为这些转换可能会影响是否可以使用索引。
“优化”这一步的下一步是使用EXPLAIN
,查看访问计划,并评估我们期望使用的索引是否未使用,或者是否添加了合适的索引索引可能会提高绩效。
EXPLAIN
https://dev.mysql.com/doc/refman/5.5/en/using-explain.html