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

时间:2018-08-23 15:19:18

标签: mysql performance join greatest-n-per-group

我的数据库中有以下表格:

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:

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:

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

我有以下查询:

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 

产品价格有很多记录,大约需要3秒的查询时间。有可能使其更快吗?

我在搜索查询中也遇到相同的问题:

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返回此:

+----+-------------+---------------+--------+---------------+---------+---------+---------------+--------+---------------------------------+
| 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                  |
+----+-------------+---------------+--------+---------------+---------+---------+---------------+--------+---------------------------------+

2 个答案:

答案 0 :(得分:1)

尝试对查询运行EXPLAIN以确定瓶颈在哪里。 内部查询中的ORDER BY日期是什么?尝试摆脱它。也可以尝试用JOIN替换内部查询,它们通常会更快。 另外,您在日期字段上有索引吗?尝试在查询末尾为ORDER BY添加一个。

答案 1 :(得分:1)

您不必在ORDER之前JOIN,如果需要订购,可以在WHEREGROUP BY之后进行排序,这样可以减少排序的数据。

JOIN 
         ( 
                  SELECT   * 
                  FROM     product_price 
                  ORDER BY date DESC) pp 

为asin创建索引,因此JOIN的{​​{1}}效率更高

ON pp.asin = pi.asin创建索引,这样user_id会更高效