简体   繁体   English

具有多个联接的慢速MySQL查询

[英]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排序,如果需要排序,可以在WHEREGROUP 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM