我想问一下下面这个查询怎么能更快地优化。无论如何,它对很多行来说都很慢。相同三个表的索引仍然不允许快速搜索非常大的表。对于任何建议,改进,我非常感谢。谢谢。
SET @timeset := 0;
SET @timeset2 := 0;
SET @previousDay := 0;
SET @previousDay2 := 0;
SET @datefrom = cast('2017-05-01 00:00:00' as datetime);
SET @dateto = cast('2017-05-15 00:00:00' as datetime);
SET @rownumFirstTable := 0;
SET @rownumSecondTable = 0;
SELECT
`hour_time_local`,
DAY(`hour_time_local`) AS `day`,
IF(DAY(`hour_time_local`) != @previousDay, @timeset:=0, @timeset:=1) AS ``,
@rownumFirstTable := IF(@timeset != 0, @rownumFirstTable :=@rownumFirstTable +1, @rownumFirstTable :=1) AS `row_first_table`,
@previousDay := DAY(`hour_time_local`),
`low_speed` AS `LOW_SPEED_15_PERCENTILE`,
`day_second_table`,
`LOW_SPEED_15_PERCENTILE_INDEX`,
`row_second_table`,
`high_speed`,
`hour_time_second_table`,
`day_second_table`,
`HIGH_SPEED_15_PERCENTILE_INDEX`
FROM
t.table_speed AS `first_table`
LEFT JOIN
(
SELECT
COUNT(low_speed) AS `count_low_speed`,
CEIL((15 / 100) * COUNT(low_speed)) AS `LOW_SPEED_15_PERCENTILE_INDEX`,
CEIL((15 / 100) * COUNT(high_speed)) AS `HIGH_SPEED_15_PERCENTILE_INDEX`,
DAY(`hour_time_local`) AS `day_second_table`
FROM t.table_speed
WHERE (`hour_time_local` >= @datefrom) AND (`hour_time_local` < @dateto) AND (`traffic_id` = 'XXXXXXXX')
GROUP BY DAY(`hour_time_local`), MONTH(`hour_time_local`), YEAR(`hour_time_local`)
) AS `second_table` ON `id` = `first_table`.`id`
LEFT JOIN
(
SELECT
DAY(`hour_time_local`) AS `day_second_table`,
@timeset2 AS `timeset`,
IF(DAY(`hour_time_local`) != @previousDay2, @timeset2:=0, @timeset2:=1) AS ``,
@previousDay2 := DAY(`hour_time_local`),
IF(@timeset2 != 0, @rownumSecondTable:=@rownumSecondTable+1, @rownumSecondTable:=1),
@rownumSecondTableAS `row_second_table`,
`hour_time_local` AS `hour_time_second_table`,
`ht_high_speed` AS `high_speed`
FROM t.table_speed, (SELECT @rownumSecondTableAS :=0) AS `third_table`
WHERE (`hour_time_local` >= @datefrom) AND (`hour_time_local` < @dateto) AND (`traffic_id` = '703170016-1') AND (`ht_high_speed` > 0)
) AS `third_table` ON `id` = `first_table`.`id`
WHERE (`hour_time_local` >= @datefrom) AND (`hour_time_local` < @dateto) AND (`traffic_id` = '703170016-1') AND (`low_speed` > 0)
HAVING
(
(
(`day` = `day_first_table`) AND (`day` = `day_second_table`) AND ((`row_first_table` = `LOW_SPEED_15_PERCENTILE_INDEX`) AND (`row_second_table` = `HIGH_SPEED_15_PERCENTILE_INDEX`))
)
)
ORDER BY `hour_time_local` ASC;
答案 0 :(得分:0)
首先我想写一下,我已经找到了上述问题的解决方案。改进的查询比下面描述的查询快得多。第二,我很感激任何最后的帮助,但任何改进,帮助都是受欢迎的。
SET @timeset := 0;
SET @timeset2 := 0;
SET @previousDay := 0;
SET @previousDay2 := 0;
SET @datefrom = cast('2017-05-01 00:00:00' as datetime);
SET @dateto = cast('2017-05-15 00:00:00' as datetime);
SET @rownum_lt := 0;
SET @rownum_ht := 0;
SELECT
IF(DAY(`hour_time_local`) != @previousDay, @timeset:=0, @timeset:=1) AS ``,
@rownum_lt := IF(@timeset != 0, @rownum_lt:=@rownum_lt+1, @rownum_lt:=1) AS `row_low_speed`,
@previousDay := DAY(`hour_time_local`) AS ``,
`hour_time_local` AS `lt_hour_time_local`,
`hour_time_local_b`,
`LOW_SPEED_15_PERCENTILE_INDEX`,
`low_speed` AS `low_speed_a`,
`row_high_speed`,
`ht_hour_time_local`,
`HIGH_SPEED_15_PERCENTILE_INDEX`,
`high_speed`
FROM unicam_stats.traffic_id_hour_stats_measured AS `hs`
CROSS JOIN
(
SELECT
`hour_time_local` AS `ht_hour_time_local`,
`high_speed` AS `high_speed_ref`,
IF(DAY(`hour_time_local`) != @previousDay2, @timeset2:=0, @timeset2:=1) AS `b`,
@rownum_ht := IF(@timeset2 != 0, @rownum_ht:=@rownum_ht+1, @rownum_ht:=1) AS `row_high_speed`,
@previousDay2 := DAY(`hour_time_local`) AS `a`,
`hour_time_local_a`,
`HIGH_SPEED_15_PERCENTILE_INDEX`
FROM unicam_stats.traffic_id_hour_stats_measured AS `ht_hs`
LEFT JOIN
(
SELECT
`hour_time_local` AS `hour_time_local_a`,
CEIL((15 / 100) * COUNT(high_speed)) AS `HIGH_SPEED_15_PERCENTILE_INDEX`
FROM unicam_stats.traffic_id_hour_stats_measured AS `ht_a`
WHERE (`hour_time_local` >= @datefrom) AND (`hour_time_local` < @dateto) AND (`traffic_id` = '703170016-1')
GROUP BY DAY(`hour_time_local`), MONTH(`hour_time_local`), YEAR(`hour_time_local`)
) AS `ht_a` ON `id` = `ht_hs`.`id`
WHERE (`hour_time_local` >= @datefrom) AND (`hour_time_local` < @dateto) AND (`traffic_id` = '703170016-1') AND (`high_speed` > 0)
GROUP BY `hour_time_local`, `hour_time_local_a`
HAVING (`row_high_speed` = `HIGH_SPEED_15_PERCENTILE_INDEX` AND DAY(`ht_hour_time_local`) = DAY(`hour_time_local_a`))
) AS `ht`
LEFT JOIN
(
SELECT
`hour_time_local` AS `hour_time_local_b`,
CEIL((15 / 100) * COUNT(low_speed)) AS `LOW_SPEED_15_PERCENTILE_INDEX`
FROM unicam_stats.traffic_id_hour_stats_measured AS `lt_a`
WHERE (`hour_time_local` >= @datefrom) AND (`hour_time_local` < @dateto) AND (`traffic_id` = '703170016-1')
GROUP BY DAY(`hour_time_local`), MONTH(`hour_time_local`), YEAR(`hour_time_local`)
) AS `lt_a` ON `id` = `hs`.`id` AND `traffic_id` = `hs`.`traffic_id`
WHERE (`hour_time_local` >= @datefrom) AND (`hour_time_local` < @dateto) AND (`traffic_id` = '703170016-1') AND (`low_speed` > 0)
HAVING (`row_low_speed` = `LOW_SPEED_15_PERCENTILE_INDEX` AND DAY(`lt_hour_time_local`) = DAY(`hour_time_local_b`) AND DAY(`ht_hour_time_local`) = DAY(`hour_time_local_b`))
ORDER BY `hour_time_local`, `hour_time_local_b`, `ht_hour_time_local`