2017-07-31 61 views
-1

對於我正在處理的項目,我有一個表格,其中有兩個日期,意思是一個日期範圍,我需要一種方法來在兩個日期之間每天「增加」我的行數。MySql日曆表和表演

因此,例如我已經開始2017-07-10,結束2017-07-14 我需要有4行2017-07-10,2017-07-11,2017-07-12,2017- 07-13

爲了做到這一點,我在這裏發現有人提到使用「日曆表」與所有日期多年。

所以我建的,現在我有兩個簡單的表:

CREATE TABLE `time_sample` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `start` varchar(16) DEFAULT NULL, 
    `end` varchar(16) DEFAULT NULL, 
    PRIMARY KEY (`societa_id`), 
    KEY `start_idx` (`start`), 
    KEY `end_idx` (`end`) 
) ENGINE=MyISAM AUTO_INCREMENT=222 DEFAULT CHARSET=latin1; 

此表包含我的日期範圍,開始和結束的索引,主鍵是一個漸進的INT。 樣品行:

id start end 
1 2015-05-13 2015-05-18 

二表:

CREATE TABLE `time_dimension` (
    `id` int(11) NOT NULL, 
    `db_date` date NOT NULL, 
    PRIMARY KEY (`id`), 
    UNIQUE KEY `td_dbdate_idx` (`db_date`) 
) ENGINE=MyISAM DEFAULT CHARSET=latin1; 

這有索引,每天很多年來的日期。 樣品行:

id db_date 
20120101 2012-01-01 

現在,我所做的加入:

select * from time_sample s join time_dimension t on (t.db_date >= start and t.db_date < end); 

這需要3毫秒。即使我的第一張桌子很大,這個查詢總是很快(我見過的最大記錄是50ms,記錄很多)。

的問題我已經是當分組結果(我需要他們對我的應用程序分組):

select * from time_sample s join time_dimension t on (t.db_date >= start and t.db_date < end) group by db_date; 

這需要在第一個表中沒有那麼多行一秒鐘以上,顯着增加。爲什麼會發生這種情況,我如何避免這種情況?

更改數據類型並沒有幫助,只有一列的第二個表沒有幫助。

我能有什麼建議,請:(

+0

考慮處理應用程序代碼中的顯示問題。順便說一下,time_dimension中的id是完全多餘的。 – Strawberry

+0

你是對的,但這些只是兩個樣本表,我的實際數據庫不同。我已經測試了這兩場比賽的表現。 – D3stroyah

+0

另外,將日期存儲爲日期,並將索引置於(開始,結束)。 – Strawberry

回答

0

我不能複製這樣的結果......

我有很多日期的日曆表:日曆(DT),其中DT是一個PRIMARY KEY DATE數據型。

DROP TABLE IF EXISTS time_sample; 

CREATE TABLE time_sample (
    id int(11) NOT NULL AUTO_INCREMENT, 
    start date not NULL, 
    end date null, 
    PRIMARY KEY (id), 
    KEY (start,end) 
); 

INSERT INTO time_sample (start,end) VALUES ('2010-03-13','2010-05-09); 

SELECT * 
    FROM calendar x 
    JOIN time_sample y 
    ON x.dt BETWEEN y.start AND y.end; 
+------------+----+------------+------------+ 
| dt   | id | start  | end  | 
+------------+----+------------+------------+ 
| 2010-03-13 | 1 | 2010-03-13 | 2010-05-09 | 
| 2010-03-14 | 1 | 2010-03-13 | 2010-05-09 | 
| 2010-03-15 | 1 | 2010-03-13 | 2010-05-09 | 
| 2010-03-16 | 1 | 2010-03-13 | 2010-05-09 | 
... 
| 2010-05-09 | 1 | 2010-03-13 | 2010-05-09 | 
+------------+----+------------+------------+ 
58 rows in set (0.10 sec) 

EXPLAIN 
SELECT * FROM calendar x JOIN time_sample y ON x.dt BETWEEN y.start AND y.end; 
+----+-------------+-------+--------+---------------+---------+---------+------+------+--------------------------+ 
| id | select_type | table | type | possible_keys | key  | key_len | ref | rows | Extra     | 
+----+-------------+-------+--------+---------------+---------+---------+------+------+--------------------------+ 
| 1 | SIMPLE  | y  | system | start   | NULL | NULL | NULL | 1 |       | 
| 1 | SIMPLE  | x  | range | PRIMARY  | PRIMARY | 3  | NULL | 57 | Using where; Using index | 
+----+-------------+-------+--------+---------------+---------+---------+------+------+--------------------------+ 
2 rows in set (0.00 sec) 

即使有GROUP BY,我掙扎重現該問題。這裏有一個簡單的個性化......

SELECT SQL_NO_CACHE dt, COUNT(1) FROM calendar x JOIN time_sample y WHERE x.dt BETWEEN y.start AND y.end GROUP BY dt ORDER BY COUNT(1) DESC LIMIT 3; 
+------------+----------+ 
| dt   | COUNT(1) | 
+------------+----------+ 
| 2010-04-03 |  2 | 
| 2010-05-05 |  2 | 
| 2010-03-13 |  2 | 
+------------+----------+ 
3 rows in set (0.36 sec) 

EXPLAIN 
SELECT SQL_NO_CACHE dt, COUNT(1) FROM calendar x JOIN time_sample y WHERE x.dt BETWEEN y.start AND y.end GROUP BY dt ORDER BY COUNT(1) DESC LIMIT 3; 
+----+-------------+-------+-------+---------------+---------+---------+------+---------+----------------------------------------------+ 
| id | select_type | table | type | possible_keys | key  | key_len | ref | rows | Extra          | 
+----+-------------+-------+-------+---------------+---------+---------+------+---------+----------------------------------------------+ 
| 1 | SIMPLE  | y  | index | start   | start | 7  | NULL |  2 | Using index; Using temporary; Using filesort | 
| 1 | SIMPLE  | x  | index | PRIMARY  | PRIMARY | 3  | NULL | 1000001 | Using where; Using index      | 
+----+-------------+-------+-------+---------------+---------+---------+------+---------+----------------------------------------------+ 
+0

這個問題不是讀取而是分組。我的最後一個查詢。 select * from time_sample s加入time_dimension t on(t.db_date> = start和t.db_date D3stroyah

+0

您沒有彙總函數,所以我不明白你爲什麼要編組 – Strawberry

+0

以及我的表格,因爲我寫的很遠更大,在這種情況下,我不得不計數(*)爲每個行分組db_date,最終也做了一些其他的計算,但我們只考慮我需要按日期進行分組,因爲我認爲它是一個巨大的性能問題 – D3stroyah