以下查询在0.12秒内执行
SET @num :=0, @current_shop_id := NULL, @current_product_id := NULL;
SELECT * FROM (
SELECT fav1.user_id, @num := IF(@current_shop_id=shops.shop_id, IF(@current_product_id=products.product_id,@num,@num+1),0) AS row_number, @current_shop_id := shops.shop_id AS shop_dummy, @current_product_id := products.product_id AS product_dummy
FROM favorites fav1 INNER JOIN
products ON
fav1.product_id=products.product_id AND
fav1.current=1 AND
fav1.closeted=1 AND
fav1.user_id=30 INNER JOIN
shops ON
shops.shop_id = products.shop_id
GROUP BY fav1.product_id
ORDER BY shops.shop ASC
) AS rowed_results WHERE rowed_results.row_number>=0 AND rowed_results.row_number<(0+5)
第二个查询在0.00秒内执行
SELECT fav5.product_id AS product_id, SUM(CASE
WHEN fav5.current = 1 AND fav5.closeted = 1 THEN 1
WHEN fav5.current = 1 AND fav5.closeted = 0 THEN -1
ELSE 0
END) AS favorites_count
FROM favorites fav5
GROUP BY fav5.product_id
但是,如下组合它们会导致查询执行超过11秒
SET @num :=0, @current_shop_id := NULL, @current_product_id := NULL;
SELECT * FROM (
SELECT fav1.user_id, @num := IF(@current_shop_id=shops.shop_id, IF(@current_product_id=products.product_id,@num,@num+1),0) AS row_number, @current_shop_id := shops.shop_id AS shop_dummy, @current_product_id := products.product_id AS product_dummy
FROM
#limit results to products favorited by the user whose closet is being shown
favorites fav1 INNER JOIN
products ON
fav1.product_id=products.product_id AND
fav1.current=1 AND
fav1.closeted=1 AND
fav1.user_id=30 INNER JOIN
shops ON
shops.shop_id = products.shop_id
LEFT JOIN
# this LEFT JOIN associates favorites_count table (adds up the scores for all the products in the favorites table)
(
SELECT fav5.product_id AS product_id, SUM(CASE
WHEN fav5.current = 1 AND fav5.closeted = 1 THEN 1
WHEN fav5.current = 1 AND fav5.closeted = 0 THEN -1
ELSE 0
END) AS favorites_count
FROM favorites fav5
GROUP BY fav5.product_id
) AS fav6 ON products.product_id=fav6.product_id
GROUP BY fav1.product_id
ORDER BY shops.shop ASC
) AS rowed_results WHERE rowed_results.row_number>=0 AND rowed_results.row_number<(0+5)
如何加快速度?
第一个查询的EXPLAIN EXTENDED是
+----+-------------+------------+--------+------------------------------------------------+---------+---------+------------------------------+------+----------+----------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+------------+--------+------------------------------------------------+---------+---------+------------------------------+------+----------+----------------------------------------------+
| 1 | PRIMARY | <derived2> | ALL | NULL | NULL | NULL | NULL | 8846 | 100.00 | Using where |
| 2 | DERIVED | fav1 | ref | user_id,user_id_2,product_id,closeted | user_id | 4 | | 9624 | 100.00 | Using where; Using temporary; Using filesort |
| 2 | DERIVED | products | eq_ref | PRIMARY,shop_id,shop_id_2,product_id,shop_id_3 | PRIMARY | 4 | my_database.fav1.product_id | 1 | 100.00 | |
| 2 | DERIVED | shops | eq_ref | PRIMARY | PRIMARY | 4 | my_database.products.shop_id | 1 | 100.00 | |
+----+-------------+------------+--------+------------------------------------------------+---------+---------+------------------------------+------+----------+----------------------------------------------+
4 rows in set, 1 warning (0.12 sec)
第一个查询的显示警告是
+-------+------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Note | 1003 | select `rowed_results`.`user_id` AS `user_id`,`rowed_results`.`row_number` AS `row_number`,`rowed_results`.`shop_dummy` AS `shop_dummy`,`rowed_results`.`product_dummy` AS `product_dummy` from (select `my_database`.`fav1`.`user_id` AS `user_id`,(@num:=if(((@current_shop_id) = `my_database`.`shops`.`shop_id`),if(((@current_product_id) = `my_database`.`products`.`product_id`),(@num),((@num) + 1)),0)) AS `row_number`,(@current_shop_id:=`my_database`.`shops`.`shop_id`) AS `shop_dummy`,(@current_product_id:=`my_database`.`products`.`product_id`) AS `product_dummy` from `my_database`.`favorites` `fav1` join `my_database`.`products` join `my_database`.`shops` where ((`my_database`.`fav1`.`user_id` = 30) and (`my_database`.`products`.`product_id` = `my_database`.`fav1`.`product_id`) and (`my_database`.`shops`.`shop_id` = `my_database`.`products`.`shop_id`) and (`my_database`.`fav1`.`current` = 1) and (`my_database`.`fav1`.`closeted` = 1)) group by `my_database`.`fav1`.`product_id` order by `my_database`.`shops`.`shop`) `rowed_results` where ((`rowed_results`.`row_number` >= 0) and (`rowed_results`.`row_number` < 5)) |
+-------+------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
第二个查询的EXPLAIN EXTENDED是
+----+-------------+-------+------+---------------+------+---------+------+-------+----------+---------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------+---------------+------+---------+------+-------+----------+---------------------------------+
| 1 | SIMPLE | fav5 | ALL | NULL | NULL | NULL | NULL | 16377 | 100.00 | Using temporary; Using filesort |
+----+-------------+-------+------+---------------+------+---------+------+-------+----------+---------------------------------+
1 row in set, 1 warning (0.00 sec)
第二个查询的显示警告是
+-------+------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Level | Code | Message |
+-------+------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Note | 1003 | select `my_database`.`fav5`.`product_id` AS `product_id`,sum((case when ((`my_database`.`fav5`.`current` = 1) and (`my_database`.`fav5`.`closeted` = 1)) then 1 when ((`my_database`.`fav5`.`current` = 1) and (`my_database`.`fav5`.`closeted` = 0)) then -(1) else 0 end)) AS `favorites_count` from `my_database`.`favorites` `fav5` group by `my_database`.`fav5`.`product_id` |
+-------+------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
最终查询的EXPLAIN EXTENDED是
+----+-------------+------------+--------+------------------------------------------------+-----------+---------+------------------------------+-------+----------+----------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+------------+--------+------------------------------------------------+-----------+---------+------------------------------+-------+----------+----------------------------------------------+
| 1 | PRIMARY | <derived2> | ALL | NULL | NULL | NULL | NULL | 8846 | 100.00 | Using where |
| 2 | DERIVED | fav1 | ref | user_id,user_id_2,product_id,closeted | user_id_2 | 4 | | 9624 | 100.00 | Using where; Using temporary; Using filesort |
| 2 | DERIVED | products | eq_ref | PRIMARY,shop_id,shop_id_2,product_id,shop_id_3 | PRIMARY | 4 | my_database.fav1.product_id | 1 | 100.00 | |
| 2 | DERIVED | shops | eq_ref | PRIMARY | PRIMARY | 4 | my_database.products.shop_id | 1 | 100.00 | |
| 2 | DERIVED | <derived3> | ALL | NULL | NULL | NULL | NULL | 15764 | 100.00 | |
| 3 | DERIVED | fav5 | ALL | NULL | NULL | NULL | NULL | 16377 | 100.00 | Using temporary; Using filesort |
+----+-------------+------------+--------+------------------------------------------------+-----------+---------+------------------------------+-------+----------+----------------------------------------------+
6 rows in set, 1 warning (11.50 sec)
最终查询的显示警告是
+-------+------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Note | 1003 | select `rowed_results`.`user_id` AS `user_id`,`rowed_results`.`row_number` AS `row_number`,`rowed_results`.`shop_dummy` AS `shop_dummy`,`rowed_results`.`product_dummy` AS `product_dummy` from (select `my_database`.`fav1`.`user_id` AS `user_id`,(@num:=if(((@current_shop_id) = `my_database`.`shops`.`shop_id`),if(((@current_product_id) = `my_database`.`products`.`product_id`),(@num),((@num) + 1)),0)) AS `row_number`,(@current_shop_id:=`my_database`.`shops`.`shop_id`) AS `shop_dummy`,(@current_product_id:=`my_database`.`products`.`product_id`) AS `product_dummy` from `my_database`.`favorites` `fav1` join `my_database`.`products` join `my_database`.`shops` left join (select `my_database`.`fav5`.`product_id` AS `product_id`,sum((case when ((`my_database`.`fav5`.`current` = 1) and (`my_database`.`fav5`.`closeted` = 1)) then 1 when ((`my_database`.`fav5`.`current` = 1) and (`my_database`.`fav5`.`closeted` = 0)) then -(1) else 0 end)) AS `favorites_count` from `my_database`.`favorites` `fav5` group by `my_database`.`fav5`.`product_id`) `fav6` on(((`my_database`.`products`.`product_id` = `my_database`.`fav1`.`product_id`) and (`fav6`.`product_id` = `my_database`.`fav1`.`product_id`))) where ((`my_database`.`fav1`.`user_id` = 30) and (`my_database`.`products`.`product_id` = `my_database`.`fav1`.`product_id`) and (`my_database`.`shops`.`shop_id` = `my_database`.`products`.`shop_id`) and (`my_database`.`fav1`.`current` = 1) and (`my_database`.`fav1`.`closeted` = 1)) group by `my_database`.`fav1`.`product_id` order by `my_database`.`shops`.`shop`) `rowed_results` where ((`rowed_results`.`row_number` >= 0) and (`rowed_results`.`row_number` < 5)) |
+-------+------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
答案 0 :(得分:1)
使用子查询可创建不带任何索引的临时表。加入子查询时,您总是在进行全表扫描。
如果没有完全了解您的SQL,使用主键创建临时表可能会有效。
CREATE TEMPORARY TABLE fav6 (product_id INT, favorites_count INT, PRIMARY KEY (product_id));
INSERT INTO fav6
SELECT fav5.product_id AS product_id, SUM(CASE
WHEN fav5.current = 1 AND fav5.closeted = 1 THEN 1
WHEN fav5.current = 1 AND fav5.closeted = 0 THEN -1
ELSE 0
END) AS favorites_count
FROM favorites fav5
GROUP BY fav5.product_id;
SET @num :=0, @current_shop_id := NULL, @current_product_id := NULL;
SELECT * FROM (
SELECT fav1.user_id, @num := IF(@current_shop_id=shops.shop_id, IF(@current_product_id=products.product_id,@num,@num+1),0) AS row_number, @current_shop_id := shops.shop_id AS shop_dummy, @current_product_id := products.product_id AS product_dummy
FROM
#limit results to products favorited by the user whose closet is being shown
favorites fav1 INNER JOIN
products ON
fav1.product_id=products.product_id AND
fav1.current=1 AND
fav1.closeted=1 AND
fav1.user_id=30 INNER JOIN
shops ON
shops.shop_id = products.shop_id
LEFT JOIN
fav6 ON products.product_id=fav6.product_id
GROUP BY fav1.product_id
ORDER BY shops.shop ASC
) AS rowed_results WHERE rowed_results.row_number>=0 AND rowed_results.row_number<(0+5)