How can I speed up this query that uses the time intervals:
SELECT a2.field_a1,
MAX(a1.field_a2) AS field_a2,
MIN(a1.field_a3) as field_a3,
a3.field_a4,
SUM(a1.field_a5) as field_a5,
a1.date,
MIN(a1.time) as time
FROM tableTen a1
INNER JOIN
(
SELECT floor( (cast( SUBSTRING(time,1,2) AS SIGNED ) * 60 +
cast( SUBSTRING(time,3,2) AS SIGNED ) - 540) /5
) AS timeInterval,
MIN(time) AS minTime,
MAX(time) AS maxtime,
date as timeIntervDate
FROM tableTen
WHERE TIME >= 0900
AND time <= 1730
GROUP BY timeIntervDate, timeInterval
) Sub1 ON Sub1.timeIntervDate = a1.date
AND floor( (cast( SUBSTRING(a1.time,1,2) AS SIGNED ) * 60 +
cast( SUBSTRING(a1.time,3,2) AS SIGNED ) - 540) /5
) = Sub1.timeInterval
INNER JOIN tableTen a2 ON a2.time = Sub1.minTime AND a1.date = a2.date
INNER JOIN tableTen a3 ON a3.time = Sub1.maxtime AND a1.date = a3.date
WHERE a1.time >= 0900
AND a1.time <= 1730
GROUP BY a1.date , timeInterval
order by a1.date desc, time desc
an example of the values that contains the table is the following:
+------+--------+----------+------+-----------+-----------+------------+----------+----------+------------+----------+
| id | symbol | date | time | field_a1 | field_a2 | field_a3 | field_a4 | field_a5 | my_date | my_time |
+------+--------+----------+------+-----------+-----------+------------+----------+----------+------------+----------+
| 0 | TEN | 20120202 | 0900 | 15.06 | 15.08 | 14.98 | 15 | 31022 | 2012-02-02 | 09:00:00 |
| 1 | TEN | 20120202 | 0901 | 15.04 | 15.08 | 15.04 | 15.08 | 6834 | 2012-02-02 | 09:01:00 |
| 2 | TEN | 20120202 | 0902 | 15.06 | 15.07 | 15.06 | 15.07 | 1458 | 2012-02-02 | 09:02:00 |
+------+--------+----------+------+-----------+-----------+------------+----------+----------+------------+----------+
in order to speed up the query I have included my_date and my_time fields (see this link 1) using the steps below:
ALTER TABLE tableTen ADD my_date date;
ALTER TABLE tableTen ADD my_time time;
UPDATE tableTen SET my_date = STR_TO_DATE(date,'%Y%m%d');
UPDATE tableTen SET my_time = STR_TO_DATE(time, '%H%i');
CREATE INDEX ten_idx ON tableTen(my_date, my_time) USING BTREE;
now tableTen is:
+-----------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+-------------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| symbol | varchar(25) | YES | | NULL | |
| date | char(8) | YES | | NULL | |
| time | char(4) | YES | MUL | NULL | |
| field_a1 | double | YES | | NULL | |
| field_a2 | double | YES | | NULL | |
| field_a3 | double | YES | | NULL | |
| field_a4 | double | YES | | NULL | |
| field_a5 | int(11) | YES | | NULL | |
| my_date | date | YES | MUL | NULL | |
| my_time | time | YES | | NULL | |
+-----------+-------------+------+-----+---------+-------+
the index are
+----------+------------+--------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+----------+------------+--------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| tableTen | 1 | ten_full_idx | 1 | time | A | 582 | NULL | NULL | YES | BTREE | | |
| tableTen | 1 | ten_full_idx | 2 | date | A | 596004 | NULL | NULL | YES | BTREE | | |
| tableTen | 1 | ten_idx | 1 | my_date | A | 1159 | NULL | NULL | YES | BTREE | | |
| tableTen | 1 | ten_idx | 2 | my_time | A | 596004 | NULL | NULL | YES | BTREE | | |
+----------+------------+--------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
How can I adjust the code
floor( (cast( SUBSTRING(time,1,2) AS SIGNED ) * 60 +
cast( SUBSTRING(time,3,2) AS SIGNED ) - 540) /5)
in such a way that it use the field my_time instead of the field time ?
After completing the work, the fields date, time and their index which will no longer be needed will be removed.