sqliteに存在しないスキーマがあることを確認してください。

sqliteに存在しないスキーマがあることを確認してください。

プレーンテキストファイルで同様の状況を説明しました。巨大なファイルから多数のパターンをGrepします。。多くの人が私がこれを行う必要があると言っているので、データをsqliteデータベースに移行しています。

約10,000のパターンを抽出したファイルがあります。次に、データベースにそのスキーマが含まれていないことを確認します。それ以外の場合は、さらなるfile処理のために外部に保存する必要があります。

for id in $(grep ^[0-9] keys); do
  if [[ -z $(sqlite3 db.sqlite "select id from main where id = $id") ]]; then
    echo $id >>file
  fi
done

私はSQLに初めて触れたので、これを行う簡単な方法を見つけることができません。また、このループはawk上記のURLで実装したものより20倍遅いので役に立ちません。

データベースは大きく成長しており、このループを非常に頻繁に実行しているので、より速くすることができますか?

答え1

sqlite各モードでデータベースに再接続するプログラムの新しいインスタンスを呼び出します。本当に無駄です。キーを検索するクエリを作成し、そのクエリを実行する必要があります。データベースクライアントは、大規模なクエリを実行するのに熟練しています。

ファイルの一致する行にkeys数字のみが含まれている場合は、次のようにクエリを作成できます。

{
  echo 'select id from main where id in (';
  <keys grep -x '[0-9][0-9]*' |     # retain only lines containing only digits
  sed -e '1! s/^/, /' |             # add ", " at the beginning of every line except the first
  echo ');'
} | sqlite3 db.sqlite

より一般的な入力データの場合は、テキスト変換を使用して単一の大規模クエリを作成するアイデアを得ることができます。注意深い入力確認;ここでクエリに挿入した内容が構文的に有効であることを確認してください。上記の例では実際に極端なケースがあります。ファイルに一致がない場合、SQL構文は無効です。ファイルに一致がない場合、SQL構文は無効です。可能であれば、この状況を処理する必要があります。特に。 null ケースを処理するより複雑なコードは次のとおりです。

<keys grep -x '[0-9][0-9]*' |
if read first; then {
    echo 'select id from main where id in (' "$first"
    sed -e 's/^/, /'
    echo ');'
  } | sqlite3 db.sqlite
fi

答え2

まずifリストに変更しました。実際、私は[[]]sをsに置き換えて[]から実行するdashか、より軽いものを実行することもできますsh。これはすべてを削除しforて実行できるほど簡単に見えますxargs(常に私が好むもの、より良いパフォーマンス)。たとえば、次のようになります。

grep ^[0-9] keys | xargs -P0 -I '{id}' \
sh -c '[ -z "$(sqlite3 db.sqlite =\"select id from main where id = '{id}'\")" ] && \
echo '{id}' >> file'

私の脱出は失敗した可能性が高いですが、これはあなたに正しい方向を伝えます。少なくとも並列に実行されるので、これはより速く実行されると思います-P

何らかの理由でクロールしていても、ダンプされたsqliteデータベースの内容を常に表示できます。このアプローチを取ると、おそらくスクリプトを書くでしょう。必要な場合にのみ考慮します。

答え3

IDを新しいテーブルにインポートし、それを使用してmainテーブルをクエリします。使用後にテーブルを捨てます。

{ echo id; grep '^[0-9]' keys; } |
sqlite3 database.db \
    'CREATE TABLE ids ( id INTEGER UNIQUE )' \
    '.import /dev/stdin ids' \
    'SELECT * FROM main NATURAL JOIN ids' \
    'DROP TABLE ids'

テスト:

sqlite> .mode box
sqlite> SELECT * FROM main;
┌────┬─────────────────┐
│ id │      word       │
├────┼─────────────────┤
│ 1  │ concessionaire  │
│ 2  │ goniometrically │
│ 3  │ meshed          │
│ 4  │ Celtic          │
│ 5  │ guiltless       │
│ 6  │ sclerodactylia  │
│ 7  │ spiritism       │
│ 8  │ ratchel         │
│ 9  │ Bajau           │
│ 10 │ semimineral     │
└────┴─────────────────┘
$ cat keys
3
7
78
190

与えられたコマンドを実行すると、以下が出力されます(IDのみを出力するid代わりに選択されます)。*

3|meshed
7|spiritism

関連情報