优化 SQLite 更新

本文关键字:更新 SQLite 优化 | 更新日期: 2023-09-27 18:29:38

Class Database {
    private SQLiteConnection myDB;
    private SQLiteCommand cmd;
    public Database {
        //create database file, create connection info,  etc)
        String sql = "CREATE TABLE IF NOT EXISTS 'myTable' (id INTEGER PRIMARY KEY, user TEXT, currency INTEGER DEFAULT 0)";
        using (cmd = new SQLiteCommand(sql, myDB))
        {
            cmd.ExecuteNonQuery();
        }
    }
    public void newUser(String user) {
         String sql = "INSERT INTO myTable (user) VALUES '" + user + "'";
         cmd = new SQLiteCommand(myDB, sql);
         cmd.ExecuteNonQuery();
    }
    private bool userExists(String user) {
        String sql = "SELECT * FROM '" + channel + "';";
        using (cmd = new SQLiteCommand(sql, myDB))
        {
             using (SQLiteDataReader r = cmd.ExecuteReader())
             {
                  while (r.Read())
                  {    
                       if (r["user"].ToString().Equals(user, StringComparison.OrdinalIgnoreCase))
                       {
                           return true;
                        }
                    }
              }
          }
          return false;
    }
    public void AddCurrency(String user, int amount) {
        if (!userExists(user)) {
            newUser(user);
        }
        using (cmd = myDB.CreateCommand())
        {
            cmd.CommandText = "UPDATE '" + channel + "' SET currency = currency + @amount WHERE user = @user";
            cmd.Parameters.Add(new SQLiteParameter("@amount", amount));
            cmd.Parameters.Add(new SQLiteParameter("@user", user));
            cmd.ExecuteNonQuery();
        }
    }
}
Class Stuff {
    public void Main(String[] args) {
        Database db = new Database();
        //blah blah blah
        //blah blah blah
        //blah blah blah
        //Do stuff and generate an array called users that is alist of all the users in the channel
        //Here's what I currently do
        foreach (String person in users) {
            db.AddCurrency(person, 1);
        }       
    }
}

正如您可能看到的,这样做的问题在于,对于一个大型用户列表(例如,1000 个用户(,我可能会执行多达 3000 个查询。 它在小规模上工作正常,但是当用户列表变得太大时,它真的开始陷入困境(尤其是写入查询(。所以我想把它改成类似 db 的东西。添加货币(用户,1(;发送整个数组,但我还有其他问题。 例如,SQLite中似乎没有"更新器"(如果不存在则插入,否则更新(类型命令。 关于如何减少大型用户列表的运行时间的任何想法?

作为参考,这是 http://twitch.tv 聊天机器人的一部分。 它似乎对我当前所有用户都很好用,即使他们有多达 100 或 200 个并发查看器。 但是有一天出于好奇,我在拥有超过 4k 观众的流中运行它,完成所有数据库更新需要大约 2 分钟+。 现在这不是问题,但如果可能的话,我觉得这是我想解决的问题。

**注意:我正在使用System.Data.SQLite库。

优化 SQLite 更新

在用户列和货币列上创建索引。

CREATE INDEX 'userName' ON 'tablename' ('user' ASC);
CREATE INDEX 'currencyAMT' on 'tablename' ('currency' ASC);

创建表命令之后,在数据库构造函数中将这些命令作为单独的命令传递。这应该在列上创建索引。(我的系统ATM上没有SQLLite,所以我没有测试的能力(

此外,在 userExists 方法中,向 SQL 添加一个 where 子句,以便您可以获取一个记录集,其中用户 = 您传入的用户。

"SELECT * FROM '" + channel + "' WHERE user = '" & user & "';";

如果未取回任何记录,则用户不存在。如果您确实取回了记录,则用户确实存在。

这会将您的 O(n( 搜索减少到更类似于 O(1( 的内容。