1

私はMySQLデータベースを使用しており、指定された期間(開始日と停止日で指定)の日付間隔を指定されたステップ(たとえば1日)で生成する必要があります。

間隔を生成し、一時テーブルを作成し、このテーブルに間隔を設定するストアド プロシージャを作成しました。

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. ステップの値 (1 日、1 か月、または 1 時間) が正確にわかりません。

このような大きなテーブルを 1 つ作成します (一時的ではありません)。

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

必要な数のインデックスを作成すると、あらゆる種類のレポートに対して非常にパフォーマンスの高い強力なスイス ナイフが得られます。

: 同じテーブルに時間と日付を入れないように検討することもできます。これは、例を単純化するためです。

あなたの2番目の問題

モデルデータではないデータベースが詰まってしまいます。

問題ありません。データベースはデータを保持するために存在します。それでおしまい。スペースなどに問題がある場合、解決策はより多くのスペースを確保することであり、効率的に作業する能力を制限することではありません.

そうは言っても、このテーブルの使用方法の例をいくつか示します。

日付が必要です:

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 に答える