2013-01-23 63 views
1

我的表有以下字段:SQLite的掃描臺性能

  1. 日期(整數)
  2. 狀態(整數)
  3. 產品編號(整數)
  4. 產品名稱(整數)
  5. 說明(文字)(最大文本長度 3000個字符)

將會有超過800萬行。我需要決定是否應該將產品說明放在另一張表格中。我的主要目標是讓這個聲明非常快:

SELECT Date,State,ProductId,ProductName FROM tablename ORDER BY DATE desc LIMIT 100 

SQL結果將不會獲取上述語句中的Description字段值。只有在應用程序中選擇了行(新查詢)時,用戶纔會看到說明。

我真的想要在同一個表中有產品說明,但我不知道SQLite如何掃描行。如果日期值不匹配我會假設SQLite可以快速跳到下一行。或者,也許它需要掃描行的所有字段,直到它到達Description字段值的末尾,以便知道該行已結束?如果需要掃描所有字段以進入下一行,說明字段中的3000個字符的值會大大降低速度?

編輯:由於INSERT速度很重要,因此不應使用索引。

編輯:試圖將它全部放在一張表中的唯一原因是我想在數百個項目的一個事務中執行INSERT和UPDATE。可以在同一個事務中插入相同的項目並稍後更新,因此我無法知道每個項目的最後一個插入ID。

+0

*如何重要?查詢中的索引加速通常比INSERT的任何減速要大得多。 –

+0

您是否真的測量了INSERT性能? –

+0

是的,在應用程序設計中是不可接受的。 –

回答

1
  1. 當您使用查詢,並沒有對Date列的索引,SQLite的會從表中讀取的所有記錄,並使用臨時表來排序結果。
  2. 當您在Date列上有索引時,SQLite將查找索引中的最後100條記錄,然後從表中讀取這些記錄的所有數據。
  3. 當你有一個covering index,即一個索引與四列DateStateProductIdProductName,SQLite的將剛剛從索引讀取的最後100個條目。

每當SQLite從數據庫文件中讀取數據時,它不讀取值或記錄,而是讀取整個頁面(通常爲1 KB或4 KB)。

在情況1中,SQLite將讀取表的所有頁面。
在情況2中,SQLite將讀取索引的最後一頁(因爲100個日期將適合一個頁面)和100個頁面(每個記錄一個),假設這些記錄中沒有兩個發生在相同的頁面)。
在情況3中,SQLite將讀取索引的最後幾頁。

情況2比情況1要快得多;情況3仍然會更快,但可能不足以引起注意。

+0

抱歉,我忘記提及不應使用索引。所以我的情況是1,這意味着在掃描過程中,無論日期值是否匹配,都會讀取所有字段的值。如果說明不超過3000個字符,這會造成太多的性能差異嗎?謝謝。 –

+0

還有一個問題,如果訂單是按照ROWID(而不是日期)降序排列的,它會在情況1下進行全表掃描嗎? –

+0

示例查詢:SELECT Date,State,ProductId,ProductName FROM tablename WHERE State = 2 ORDER BY ROWID desc LIMIT 100 –

0

我會建議依靠良好的舊database normalization規則,在這種情況下,具體爲1NF。如果該說明(對於ProductName也是如此)將會重複出現,那麼您將遇到數據庫設計問題,並且它在SQLite或其他版本中與它無關。 CL對他的索引是正確的,請注意,適當的索引仍然很重要。

查看您的模型,爲產品製作表格,爲庫存製作另一個表格。