Вставка быстрее из Sqlite с другого стола - PullRequest
0 голосов
/ 21 февраля 2020

У меня есть Sqlite DB, на которой я делаю обновления, и она очень медленная. Мне интересно, делаю ли я это наилучшим образом или есть более быстрый способ. Мои таблицы:

create table files( 
    fileid integer PRIMARY KEY,
    name TEXT not null,
    sha256 TEXT,
    created INT,
    mtime INT,
    inode INT,
    nlink INT,
    fsno INT,
    sha_id INT,
    size INT not null
);

create table fls2 (
    fileid integer PRIMARY KEY,
    name TEXT not null UNIQUE, 
    size INT not null, 
    sha256 TEXT not null, 
    fs2, 
    fs3, 
    fs4, 
    fs7
);

Таблица 'files' фактически находится в присоединенной БД с именем ttb. Затем я делаю это:

UPDATE fls2 
SET fs3 = (
SELECT inode || 'X' || mtime || 'X' || nlink 
FROM 
   ttb.files
WHERE 
   ttb.files.fsno = 3 
AND 
   fls2.name = ttb.files.name 
AND
   fls2.sha256 = ttb.files.sha256
);

Итак, идея в том, что fls2 имеет значения в «name», которые также присутствуют в ttb.files.name. В ttb.files есть другие параметры, которые я хочу вставить в соответствующие строки в fls2. Запрос работает, но я предполагаю, что сопоставление двух таблиц занимает время, и мне интересно, есть ли более эффективный способ сделать это. В fls2 есть индексы для каждого столбца, но нет файлов. Я делаю это как транзакцию, и pragma journal = memory (хотя sqlite, похоже, игнорирует это, потому что создается файл журнала).

Это кажется медленным, примерно 90 минут для примерно миллиона строк в каждой таблице.

Один ЦП привязан, поэтому я предполагаю, что он не связан с диском.

Может кто-нибудь предложить лучший способ структурировать запрос?

РЕДАКТИРОВАТЬ: EXPLAIN QUERY PLAN

|--SCAN TABLE fls2
`--CORRELATED SCALAR SUBQUERY 1
   `--SCAN TABLE files

Не уверен, что это значит, хотя. Он выполняет файлы SCAN TABLE для каждого попадания SCAN TABLE fls2?

EDIT2: Хорошо, блайми, Crtl- C запрос, который выполнялся в течение 2,5 часов, выйдите из Sqlite, запустите sqlite с файлами БД, создать индекс (sha256, имя) - 1 минута или около того. Выйдите, запустите Sqlite с основной БД. Объясните, показывает, что теперь последнее сканирование выполняется с индексом. Запустить обновление - занимает 150 секунд. По сравнению с> 150 минутами, это невероятная скорость. Спасибо за помощь.

TIA, Пит

Ответы [ 2 ]

0 голосов
/ 21 февраля 2020

Не эксперт по sqlite, но в некоторых базах данных более эффективно вставлять данные во временную таблицу, удалять их, а затем вставлять из временной таблицы.

Insert into tmptab
Select fileid,
    name,
    size,
    sha256,
    fs2, 
    inode || 'X' || mtime || 'X' || nlink,
    fs4, 
    fs7
From fls2
Inner join files on 
   fls2.name = ttb.files.name 
AND
   fls2.sha256 = ttb.files.sha256

delete from
Fls2 where exists (select 1 from tmptab where tmptab.<primary key> = fls2.<primary key>)

Insert into fls2  select * from tmptab
0 голосов
/ 21 февраля 2020

В каждом столбце есть fls2

Для более быстрого выбора используются индексы. Они замедляют вставки и обновления. Может быть, удаление одного для fls2.fs3 поможет?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...