2017-10-11 12 views
0

我一直在運行一個查詢,通過匹配來自另一個表的ID來向表中添加一列。兩者都有大約6億行,所以這是合理的,這將需要一段時間,但令人擔憂的是,磁盤上的讀取速度很高(〜500MB/s),但根據iotop,sqlite正在寫入0B/s。我的.db文件上的文件大小在幾個小時內沒有改變,但向6億行表添加一列應至少改變一個字節,不是?是高讀,但絕對沒有寫在SQLite查詢正常?

這是SQLite的正常行爲嗎?該機器非常強大,四核i7上的Ubuntu 16具有64GB RAM和NVMe SSD。查詢和表格架構如下。

ALTER TABLE tableA ADD address TEXT; 
UPDATE tableA SET address = (SELECT address FROM tableB WHERE tableA.ID = tx_out.ID); 

Table schema: 
CREATE TABLE tableA (
    ID TEXT, 
    column1 INT, 
    column2 TEXT, 
); 

CREATE TABLE tx_out (
    ID TEXT, 
    sequence INT, 
    address TEXT 
); 
+1

也許寫入事務日誌第一? [WAL](https://sqlite.org/wal.html) – lad2025

+0

@ lad2025可能,我發現一個-journal文件根據這個文件https://sqlite.org/tempfiles.html但它只有25KB,是正常的對於這麼大的交易? – jamzsabb

回答

2

添加列在磁盤上幾乎沒有任何變化;一個具有比該表具有更少列的值的行假定在缺少的列中具有NULL。

更新非常慢,因爲子查詢具有通過整個tx_outtableA掃描每一行。 您可以使用tx_out.ID列中的索引大大提高速度。

當數據庫反正重寫所有行,和你有磁盤空間,這可能是一個更好的主意,以創建一個新表:

INSERT INTO NewTable(ID, col1, col2, address) 
SELECT ID, col1, col2, address 
FROM tableA 
JOIN tableB USING (ID);  -- also needs an index to be fast 
+0

這很有道理,我沒有磁盤空間來製作表格副本,但索引聽起來像是一個好主意。如果有人來自Google,那麼本指南http://www.sqlitetutorial.net/sqlite-index/確實幫助我理解了索引的WTF以及如何使用它們。感謝您的建議@CL – jamzsabb

+1

@jamzsabb - 記住索引也會佔用磁盤空間。 – Twelfth

1

太大評論

我有這個運行與沒有改變天...我認爲這是容易出現一種方式或其他鎖定本身,我殺了它,它的第三後似乎沒有任何變化的一天。在嘗試添加新索引時,我遇到了非常類似的問題,但是在我打開3天殺戮閾值之前的2天內,該問題已成功完成;)可能的3天還不夠?

我現在的首選是創建第二個具有新列的表,使用舊數據加上新列加載表,將舊錶重命名爲X_oldtablename,將新表重命名爲表名。在確信新表正在工作後運行測試並刪除x_oldtablename

+0

是的,我現在絕對關心,沒有硬盤空間來製作副本,但另一個用戶建議索引,所以我現在就這樣做。也許這對您的聯接也有幫助?祝你好運 – jamzsabb