'How to solve usng temporary;using filesort using MySQL SELET SELECT UNION SELECT
I have this query:
SELECT *
FROM
(SELECT a.id AS id,
a.user_id AS user_id,
aa.power * a.amount AS total_power,
a.group_number AS group_number,
a.amount AS total_amount,
aa.type AS TYPE
FROM units a
JOIN unit_diagrams aa ON a.diagram_id = aa.id
WHERE a.group_id = 0
AND a.current_x = 1
AND a.current_y = 1
AND a.movement_start_time = 0
UNION SELECT MIN(b.id) AS id,
MIN(b.user_id) AS user_id,
SUM(bb.power * b.amount) AS total_power,
MAX(b.group_number) AS group_number,
SUM(b.amount) AS total_amount,
MIN(bb.type) AS TYPE
FROM units b
JOIN unit_diagrams bb ON b.diagram_id = bb.id
WHERE b.group_id != 0
AND b.current_x = 1
AND b.current_y = 1
AND b.movement_start_time = 0
GROUP BY b.group_id) hello
ORDER BY group_number ASC,
total_power DESC
LIMIT 10,
10
When I run explain on it I get:
+----------------------------------+--------------+------------+--------+-------------------------------------------------------+---------------------------------+------+--------------------------------------------+------+----------------------------------------------+--+
| | | | | | | | | | | |
+----------------------------------+--------------+------------+--------+-------------------------------------------------------+---------------------------------+------+--------------------------------------------+------+----------------------------------------------+--+
| | | | | | | | | | | |
| | | | | | | | | | | |
| 1 | PRIMARY | <derived2> | ALL | NULL | NULL | NULL | NULL | 123 | Using filesort | |
| 2 | DERIVED | aa | index | PRIMARY,unit_diagrams_idx_id_power_type | unit_diagrams_idx_id_power_type | 12 | NULL | 6 | Using index | |
| 2 | DERIVED | a | ref | current_x,select_units_on_loc,units_idx_id_x_y_tim... | select_units_on_loc | 20 | const,const,const,const,gpar_game_db.aa.id | 5 | Using index | |
| 3 | UNION | b | ref | current_x,select_units_on_loc,units_idx_id_x_y_tim... | current_x | 8 | const,const | 93 | Using where; Using temporary; Using filesort | |
| 3 | UNION | bb | eq_ref | PRIMARY,unit_diagrams_idx_id_power_type | PRIMARY | 4 | gpar_game_db.b.diagram_id | 1 | | |
| NULL | UNION RESULT | <union2,3> | ALL | NULL | NULL | NULL | NULL | NULL | | |
| 4 | -2,027.1 | | | | | | | | | |
| | | | | | | | | | | |
+----------------------------------+--------------+------------+--------+-------------------------------------------------------+---------------------------------+------+--------------------------------------------+------+----------------------------------------------+--+
I have this indexes on both tables units and user_diagrams:
ALTER TABLE `units`
ADD PRIMARY KEY (`id`),
ADD KEY `current_x` (`current_x`,`current_y`),
ADD KEY `to_x` (`to_x`,`to_y`),
ADD KEY `select_units_on_loc` (`group_id`,`movement_start_time`,`current_y`,`current_x`,`diagram_id`,`id`,`user_id`,`group_number`,`amount`),
ADD KEY `units_idx_id_x_y_time_id` (`group_id`,`current_x`,`current_y`,`movement_start_time`,`diagram_id`);
ALTER TABLE `units`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;
ALTER TABLE `unit_diagrams`
ADD PRIMARY KEY (`id`),
ADD KEY `user_id_index` (`user_id`),
ADD KEY `unit_diagrams_idx_id_power_type` (`id`,`power`,`type`);
ALTER TABLE `unit_diagrams`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;
The table is not very big yet as I am just testing the app now, but even now the query is slower than other parts of my app. If I do profile it executed in about 0.007-0.011 sec, which it too slow, and I am sure this is because of the temporary/filesort. How to optimise this query?
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|