[英]Slow mysql query with multiple joins
I have the following tables in my database: 我的数据库中有以下表格:
product_fav: product_fav:
CREATE TABLE `product_fav` (
`user_id` int(9) unsigned NOT NULL,
`asin` varchar(10) NOT NULL DEFAULT '',
`date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`price` decimal(7,2) NOT NULL,
PRIMARY KEY (`user_id`,`asin`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
product_info: product_info:
CREATE TABLE `product_info` (
`asin` varchar(10) NOT NULL,
`name` varchar(200) DEFAULT NULL,
`brand` varchar(50) DEFAULT NULL,
`part_number` varchar(50) DEFAULT NULL,
`url` text,
`image` text,
`availabillity` tinyint(1) NOT NULL DEFAULT '1',
PRIMARY KEY (`asin`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
product_price: product_price:
CREATE TABLE `product_price` (
`asin` varchar(10) NOT NULL,
`date` date NOT NULL,
`timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`price` decimal(7,2) NOT NULL DEFAULT '0.00',
PRIMARY KEY (`asin`,`date`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
I have the following query: 我有以下查询:
SELECT pi.*,
pp.price,
pf.date,
pf.price AS price_added,
round((100.0 (pp.price - pf.price) / pf.price),0) AS percentdiff
FROM product_info pi
JOIN
(
SELECT *
FROM product_price
ORDER BY date DESC) pp
ON pp.asin = pi.asin
JOIN product_fav pf
ON pp.asin = pf.asin
WHERE pf.user_id=". $user['user_id'] ."
GROUP BY asin
Product price has many records and query needs about 3 second. 产品价格有很多记录,查询需要大约3秒。 Is it possible to make it faster?
有可能使其更快吗?
I have also the same issue with search query: 我对搜索查询也有同样的问题:
SELECT pi.*,
price,
date
FROM product_info pi
JOIN (SELECT *
FROM product_price
ORDER BY date DESC) pp
ON pi.asin = pp.asin
WHERE ( ` NAME ` LIKE '%".$search."%' )
GROUP BY pi.asin
ORDER BY price
EXPLAIN return this: 解释返回此:
+----+-------------+---------------+--------+---------------+---------+---------+---------------+--------+---------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------------+--------+---------------+---------+---------+---------------+--------+---------------------------------+
| 1 | PRIMARY | <derived2> | ALL | NULL | NULL | NULL | NULL | 106709 | Using temporary; Using filesort |
| 1 | PRIMARY | pi | eq_ref | PRIMARY | PRIMARY | 32 | pp.asin | 1 | |
| 1 | PRIMARY | pf | eq_ref | PRIMARY | PRIMARY | 36 | const,pp.asin | 1 | |
| 2 | DERIVED | product_price | ALL | NULL | NULL | NULL | NULL | 112041 | Using filesort |
+----+-------------+---------------+--------+---------------+---------+---------+---------------+--------+---------------------------------+
Try running an EXPLAIN on your query to figure out where the bottle-neck is. 尝试对查询运行EXPLAIN以确定瓶颈在哪里。 What's with the ORDER BY date in the inner query?
内部查询中的ORDER BY日期是什么? Try getting rid of it.
尝试摆脱它。 Also try replacing the inner query with a JOIN, they tend to be faster.
也可以尝试用JOIN替换内部查询,它们通常会更快。 Also, do you have an index on the date field?
另外,您在日期字段上有索引吗? Try adding one for the ORDER BY at the end of the query.
尝试在查询末尾为ORDER BY添加一个。
You dont ORDER
before JOIN
, If you need order do it after the WHERE
and GROUP BY
so less data to sort. 您无需在
JOIN
之前进行ORDER
排序,如果需要排序,可以在WHERE
和GROUP BY
之后进行排序,以减少排序的数据量。
JOIN
(
SELECT *
FROM product_price
ORDER BY date DESC) pp
Create index for asin so JOIN
for ON pp.asin = pi.asin
will be more efficient 为asin创建索引,以便为
ON pp.asin = pi.asin
进行JOIN
会更有效
Create index for user_id
so the WHERE pf.user_id=". $user['user_id'] ."
为
user_id
创建索引,以便在WHERE pf.user_id=". $user['user_id'] ."
will be more efficient 会更有效率
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.