2017-10-11 8 views
0

私は、別のテーブルのIDを照合してテーブルにカラムを追加するクエリを実行しています。どちらも約6億行ありますので、これには時間がかかりますが、ディスクには高い読み取り速度(〜500MB/s)がありますが、sqliteはiotopに従って0B/sを書いています。私の.dbファイルのファイルサイズは数時間で変更されていませんが、6億行のテーブルに列を追加すると、少なくとも1バイトは変更されますか?読み込み率は高いですが、SQLiteクエリでは書き込みはありません。

これはSQLiteの通常の動作ですか?このマシンはかなり強力で、64GB RAMとNVMe SSDを搭載したクアッドコアi7のUbuntu 16です。クエリとテーブルスキーマは以下のとおりです。それは第三だ後

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があるとみなされます。サブクエリがtableAに各行ためtx_outテーブル全体をスキャンする必要があるため

UPDATEは非常に遅いです。 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 - Indexesもディスクスペースを取ることを覚えておいてください。 – Twelfth

1

私は変更せずに日間、この実行を持っていたコメント

には大きすぎる...私はそれが一つの方法または別の自分自身をロックしがちだと思う、私はそれを殺しました変化のないものの日。私は新しいインデックスを追加しようとすると非常に似た問題に遭遇しましたが、私は3日間の殺害の閾値を打つ前に2日間で正常に完了しました;)3日間で十分ではありませんでしたか?

ここでは、新しい列を持つ2番目の表を作成し、古い列と新しい列のデータで表をロードし、古い表の名前をX_oldtablenameに変更して、新しい表の名前を表名に変更します。新しいテーブルが動作していると確信した後、テストを実行してx_oldtablenameをドロップします。

+0

確かに今私は間違いなくHDDのスペースをコピーして作成していないが、他のユーザーがインデックスを推奨しているので、今私はそれをやっている。多分あなたの結合にも役立つだろうか?幸運の男 – jamzsabb

関連する問題