爲了獲得最佳性能,需要有對datetime
字符串列一個合適的索引。我會建議(不一定建議)一種避免一些其他查詢模式潛在性能問題的方法。
我建議的方法是利用多個查詢,每個查詢返回一個包含新的年份值的單行。 (我假定將有隻有幾個不同的年份值,很多行對於給定的一年。)
讓我們假設我現有的幾年列表包含2011年,2013年和2014年
以下描述了我將運行的查詢的順序,利用現有的值作爲我運行的查詢中的謂詞。基本的想法是,我只需要在給定的一年中找到一行......不需要讀取全部的行。
我需要現有的年份列表才能順利。我會從最低值開始,然後運行一個查詢,獲得該年之前的最早日期。我希望能夠最有效地使用索引的查詢以及Sqllite中的優化。
我在現有列表中的最早年份值是'2011'。我推說進入查詢......我的第一個鏡頭會是這樣的:
select dt from t where dt < '2011-01-01'
order by dt limit 1
如果我沒有得到行了,我知道,2011年是最早的一年。
如果我確實得到了一排,我知道這是一個「新」年。我會將前四個字符作爲年份,並將其添加到我的列表中。我會比較2011年的這一年的價值,如果差距超過一個,我會檢查下一個最低年份。
例如,如果該查詢返回與「2008」的開始日期,下一個查詢我運行與2008年後的最低日期時間與上年行檢查,但在2011年之前
select dt from t where dt < '2011-01-01'
and dt >= datetime('2008-01-01','+1 years')
order by dt limit 1
如果我沒有再回來,我知道在2011年之前沒有更多的「新」年值。我的下一個查詢將使用2011年作爲下限,並且我現有列表中的下一年值將作爲上限,並且再次重複相同的查詢。
如果我得到行回來了,日期時間,隨着2009年開始我要補充2009年進入我的列表,我的下一個查詢酷似上面的一個,但與2009年到位2008 ...
select dt from t where dt < '2011-01-01'
and dt >= datetime('2009-01-01','+1 years')
order by dt limit 1
同樣地,如果我沒有得到一排,那時我才知道有沒有更多的新的一年在2011年之前
所以,現在2011年是我的下界,並於次年在我現有的列表上限。所以,同樣的查詢再次,只有改變了一年的文字...
select dt from t where dt < '2013-01-01'
and dt >= datetime('2011-01-01','+1 years')
order by dt limit 1
如果我得到一排,這是一個新的一年裏要添加到我的名單。這是我下一個查詢的新下界。如果沒有行,那麼最後一個查詢的上限是新的下限。
爲了優化模式,我會跳過運行一個我知道不會返回一行的查詢。當我已經有2013年和2014年在我的名單,我的查詢將是這種模式的......
select dt from t where dt < '2014-01-01'
and dt >= datetime('2013-01-01','+1 years')
order by dt limit 1
,但我們知道,有同時滿足這兩個條件的任何行。一行不能有小於2014並且大於或等於2014的dt值,這是不可能的條件,所以我們可以跳過執行它。
當我到達列表中的最後一個值時,我將刪除上限條件......我不在乎下一個查詢是否返回2015年,2017年或2032年...無論是最近一年我在我的名單中。
select dt from t where
dt >= datetime('2014-01-01','+1 years')
order by dt limit 1
如果我收回一行,將該年添加到列表中,並將其用作我的下一個下限。並重復,直到我沒有排隊回來。
這確實運行了幾個查詢,但它們應該非常有效。在Hugh Jass表格中,這些可能是查找新年值最有效的查詢。
如果這種模式發生故障,那麼當我們需要運行大量查詢時,當我們需要檢查很多「空白」時。
這種模式最糟糕的情況將是以數字結尾的數百個現有年份值。每年的價值都有差距,我們必須檢查它們之間的差距。
但是這種模式的最好情況是連續年值的長列表。如果沒有找到新的年份值,我們最多可以運行兩個查詢。一個檢查較早的一年(未找到),另一個檢查較晚的一年(未找到)。
同樣,這種方法的性能完全取決於其對dt
一個適當的索引和查詢計劃,有效地使用該索引的。
我們不一定需要使用'datetime'函數向日期文本添加一年,我們可以輕鬆地在客戶端上處理該日期,並將年份值加1。 (我使用datetime函數來說明我們使用的是我們檢索的年份值,或者是在我們的列表中。這還假定「日期時間字符串」列以一致的格式存儲,並且前導日期部分位於格式爲「'yyyy-mm-dd'」 – spencer7593
如果我們從一個現有的年份值列表開始,它是* empty *,我們的第一個查詢在dt列上將沒有謂詞(條件),只是最早得到 – spencer7593
謝謝對於這個有趣的算法的仔細解釋!順便說一句,你的假設是正確的:雖然數據庫可能用於說30年,但在大多數時間,我將有一個連續的同一年的條目列表(這將有相同的格式,'yyyy/MM/dd'。 – Momergil