1

我正在使用 MySQL 数据库,我必须使用指定的步骤(例如一天)生成指定时间段(由开始和停止日期指定)的日期间隔。

我编写了一个存储过程来生成间隔,创建一个临时表并用间隔填充这个表。

DELIMITER $$
CREATE PROCEDURE showu(IN start date, IN stop date)
BEGIN

   CREATE TEMPORARY TABLE intervals(single_day DATE);
   next_date: LOOP
         IF start>stop THEN
            LEAVE next_date;
         END IF;
         INSERT INTO intervals(single_day) VALUES(start); 
         SET start = DATE_ADD(start, INTERVAL 1 DAY);
   END LOOP next_date;

END$$
DELIMITER ;

我想在连接查询中使用这个临时表。但是我遇到了一个问题。当我调用过程调用showu('2008-01-09', '2010-02-09');时,它执行大约 30 秒。为什么它执行这么长时间的问题?有没有可能改进它?如果这个解决方案是错误的,我该如何以不同的方式解决我的问题?

4

1 回答 1

1

来自评论:

2个大问题: 1.我不知道确切的步骤值(一天或一个月或一小时)。

像这样创建一个大表一次(不是临时的):

full_date | year | month | day | full_time | hour | minute | is_weekend | whatever
----------------------------------------------------------------------------------
...

根据需要创建尽可能多的索引,您将拥有一把非常高性能的强大瑞士刀来处理各种报告。

注意:您可能会考虑在同一个表中没有时间和日期。这只是为了简化示例。

你的第二个问题

我将用非模型数据阻塞我的数据库。

没问题。数据库是用来保存数据的。而已。如果您在空间或其他方面遇到问题,解决方案是获得更多空间,而不是限制您高效工作的能力。

话虽如此,这里有一些示例如何使用此表。

您需要日期:

SELECT
*
FROM
(
   SELECT full_date AS your_step 
   FROM your_new_swiss_army_knife 
   WHERE `year` = 2012 
   GROUP BY full_date
) dates
LEFT JOIN your_tables_that_you_want_to_build_a_report_on y ON dates.your_step = y.date

与月份相同:

SELECT
*
FROM
(
   SELECT CONCAT(year, '-', month) AS your_step 
   FROM your_new_swiss_army_knife 
   WHERE full_date BETWEEN this AND that
   GROUP BY year, month
) dates
LEFT JOIN your_tables_that_you_want_to_build_a_report_on y ON dates.your_step = CONCAT(YEAR(y.date), '-', MONTH(y.date))
于 2013-09-04T10:02:46.813 回答