2013-02-01 51 views
1

我有一個數據庫表,它有三列:一個ID,一個時間戳和一個字符串。每天插入大約14,000行,所以桌子非常大。它目前有130萬行。使用針對大型表的範圍WHERE子句優化SQL查詢

表定義:

CREATE TABLE readings (
    id int primary key auto_increment, 
    ts datetime not null, --the timestamp 
    json text not null --the string 
); 

我跑的查詢是:

SELECT * FROM readings WHERE ts >= 'TIME_START' AND ts <= 'TIME_END' ORDER BY ts 

查詢需要大約45秒執行。如何修改表格和/或查詢以使其更快?

謝謝。

回答

5

在表上添加一個新的索引ts

+0

我以爲只有在指定列的特定值而不是值的範圍時,索引才起作用。例如:'WHERE ts ='TIME'' – Michael

+0

@Michael:它可能取決於數據庫,但我通常會認爲這適用於大多數數據庫。對於一個特定的值,性能仍然會更好,但是一系列的值應該可以工作(假設範圍不是太寬) - 我實際上有一個這樣的實例(在Oracle數據庫上),查詢性能從大約60秒,不到一秒鐘。 –

+0

在哪個點被認爲是「太寬」的範圍?你認爲MySQL支持這個嗎? – Michael

0

您可以使用自動增量的主ID對結果進行排序。

+0

ID和時間戳未對齊。換句話說,ID越高,時間戳越高是不正確的。 – Michael

0

嘗試下面的查詢。如果該指數的ID,這可能會更快

declare @min_id as int 
declare @max_id as int 

select @min_id = min(id) 
from readings WHERE ts = 'TIME_START' 

select @max_id = max(id) 
from readings WHERE ts = 'TIME_END' 

SELECT * FROM readings 
id between @min_id and @max_id order by id 
+0

ID和時間戳未對齊,因此ID越高,時間戳越高是不正確的。 – Michael

+0

然後你需要返回到由ts命令,但他的查詢應該仍然運行得更快,因爲條件是在ID可能是你的索引 – pranag

+0

如果我使'TS'索引,這會有幫助嗎? – Michael

1

是進入我的腦海裏都partitions假設你設置的一切權利的唯一的事情。你也可能想嘗試不同的數據庫引擎(例如InnoDB)。或者在ts列中設置索引。

除此之外 - 使用> = < = vs BETWEEN不會產生任何性能影響,所以請不要擔心。

+0

謝謝,可能會嘗試按月分區。 – Michael