删除已排序的SQLite列中的编号间隔

时间:2017-12-27 22:39:37

标签: sqlite parallel.foreach

SQLite-DB中的

是一个包含两行(ID,Start)的表。当表按开始列排序时,ID必须具有连续编号。

当前内容示例:

ID {0,44,88,132 ...}开始{0,44,88,132 ...}

我需要的结果:

ID {1,2,3,4 ...}和开始{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我无法在连续编号中按时间顺序获取ID列。对于串行循环,我不需要上面的代码,结果很好,但对于大型表来说速度较慢。

目前我唯一可以接受的解决办法是放弃Parallel.ForEach并返回正常的ForEach。

要解决的问题概述如下: -

ID不是rowid。

我有一个分析文本的标记器,我需要一个变量来识别文本中的每个标记/单词及其订单号。

这样可以找到文本结构,例如 显示所有文本部分,其中辅助动词后面跟着动词的连续形式: e,g: -

我们现在正在游泳 (发现"正在游泳"),这将是SELECT .... WHERE t1.Attr='aux' and t2.Attr='converb' and t1.id=t2.id-1

1 个答案:

答案 0 :(得分:0)

使用单个SQL语句可以完成分配连续ID:

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

但是,为每个条目执行单个UPDATE可能会更快,因为数据库不必对每一行进行计数。

在任何情况下,两种算法都需要Start列上的索引才能有效。