Удаление пробелов в нумерации внутри отсортированного столбца SQLite

внутри SQLite-DB есть таблица с двумя строками (ID, Start). Когда таблица отсортирована по начальному столбцу, идентификатор должен иметь сквозную нумерацию.

Пример текущего содержания:

ID {0, 44, 88, 132...} Начало {0, 44, 88, 132...}

Результат, который мне нужен:

ID {1, 2, 3, 4...} и Start {0, 44, 88, 132...}

Этот код для исправления ID-столбца работает, но для больших таблиц требуется много времени:

        using (var transaction = conn.BeginTransaction())
        {
            using (var cmdRows = new SQLiteCommand(
                "SELECT Start FROM Tokens ORDER BY Start ASC;", conn))
            {
                using (SQLiteDataReader reader = cmdRows.ExecuteReader())
                {
                    int id = 0;
                    while (reader.Read())
                    {
                        id += 1;
                        var cmdID = new SQLiteCommand(conn);
                        cmdID.CommandText =
                            "UPDATE Tokens SET ID=" + id.ToString() +
                            " WHERE Start=" + reader["Start"].ToString();
                        cmdID.ExecuteNonQuery();
                    }
                }
            }
            transaction.Commit();
        }

Код, который генерирует 3 таблицы и выполняется непосредственно перед этим, содержит 3 цикла (1 вложенный и еще один вложенный во вложенные). Внешний цикл выполнен как Parallel.ForEach, что увеличивает скорость в 2 раза. Но в дополнение к приведенному выше коду он работает в проблеме скорости для больших таблиц. С Parallel.ForEach я не могу получить хронологический идентификатор столбца в непрерывной нумерации. С последовательными циклами мне не нужен приведенный выше код, результат хороший, но медленнее для больших таблиц.

На данный момент мое единственное приемлемое решение — отказаться от Parallel.ForEach и вернуться к обычному ForEach.

Обзор того, что пытается решить: -

ID не является rowid.

У меня есть токенизатор, который анализирует текст, и мне нужна переменная, которая идентифицирует каждый токен/слово в тексте с его порядковым номером.

Это позволяет находить структуру текста, такую ​​как Показать всю текстовую часть, где за вспомогательным глаголом следует непрерывная форма глагола: например:-

В Мы плаваем сейчас (найдите "плавают"), что будет SELECT .... WHERE t1.Attr='aux' and t2.Attr='converb' and t1.id=t2.id-1


person Peter Gast    schedule 27.12.2017    source источник
comment
Какую настоящую проблему вы пытаетесь решить?   -  person CL.    schedule 28.12.2017
comment
У меня есть токенизатор, который анализирует текст, и мне нужна переменная, которая идентифицирует каждый токен/слово в тексте с его порядковым номером. Это позволяет найти такую ​​структуру текста, как Показать все части текста, в которых за вспомогательным глаголом следует непрерывная форма глагола: например, g :- In < i>Мы сейчас плаваем (найти плаваем), что было бы SELECT .... WHERE t1.Attr='aux' and t2.Attr='converb' and t1.id=t2.id-1   -  person Peter Gast    schedule 30.12.2017


Ответы (1)


Назначение последовательных идентификаторов может быть выполнено с помощью одного оператора SQL:

UPDATE Tokens
SET ID = (SELECT count(*)
          FROM Tokens AS T2
          WHERE T2.Start <= Tokens.Start);

Однако выполнение одного UPDATE для каждой записи, скорее всего, будет быстрее, потому что базе данных не нужно выполнять подсчет для каждой строки.

В любом случае, оба алгоритма нуждаются в индексе для столбца Start, чтобы быть эффективными.

person CL.    schedule 30.12.2017
comment
Этот SQL работает и идеально подходит для небольших таблиц. Но для больших таблиц (>100 тыс. строк) это занимает пару минут, даже если столбцы проиндексированы. - person Peter Gast; 31.12.2017
comment
Он перезаписывает каждую строку таблицы, т. е. всю таблицу. - person CL.; 31.12.2017