【问题标题】:c# - Optimize SQLite Select statementc# - 优化 SQLite Select 语句
【发布时间】:2012-07-24 12:05:50
【问题描述】:

我正在为我的数据库使用 System.Data.SQLite,而我的选择语句非常慢。查询大约 5000 行数据大约需要 3-5 分钟。这是我正在使用的代码:

        string connectionString;
        connectionString = string.Format(@"Data Source={0}", documentsFolder + ";Version=3;New=False;Compress=True;");
        //Open a new SQLite Connection
        SQLiteConnection conn = new SQLiteConnection(connectionString);
        conn.Open();

        SQLiteCommand cmd = new SQLiteCommand();
        cmd.Connection = conn;
        cmd.CommandText = "Select * From urls";
        //Assign the data from urls to dr
        SQLiteDataReader dr = cmd.ExecuteReader();

        SQLiteCommand com = new SQLiteCommand();
        com.CommandText = "Select * From visits";
        SQLiteDataReader visit = com.ExecuteReader();

        List<int> dbID2 = new List<int>();
        while (visit.Read())
        {
            dbID2.Add(int.Parse(visit[1].ToString()));
        }
        //Read from dr
        while (dr.Read())
        {
            string url = dr[1].ToString();
            string title = dr[2].ToString();
            long visitlong = Int64.Parse(dr[5].ToString());
            string browser = "Chrome";
            int dbID = int.Parse(dr[0].ToString());
            bool exists = dbID2.Any(item => item == dbID);
            int frequency = int.Parse(dr["visit_count"].ToString());

            bool containsBoth = url.Contains("file:///");

            if (exists)
            {
                if (containsBoth == false)
                {
                    var form = Form.ActiveForm as TestURLGUI2.Form1;

                    URLs.Add(new URL(url, title, browser, visited, frequency));
                    Console.WriteLine(String.Format("{0} {1}", title, browser));
                }
            }

        }
        //Close the connection
        conn.Close();

这是另一个需要很长时间的示例:

IEnumerable<URL> ExtractUserHistory(string folder, bool display)
{
    // Get User history info
    DataTable historyDT = ExtractFromTable("moz_places", folder);

    // Get visit Time/Data info
    DataTable visitsDT = ExtractFromTable("moz_historyvisits",
                                           folder);



    // Loop each history entry
    foreach (DataRow row in historyDT.Rows)
    {
        // Select entry Date from visits
        var entryDate = (from dates in visitsDT.AsEnumerable()
                         where dates["place_id"].ToString() == row["id"].ToString()
                         select dates).LastOrDefault();
        // If history entry has date
        if (entryDate != null)
        {
            // Obtain URL and Title strings
            string url = row["Url"].ToString();
            string title = row["title"].ToString();
            int frequency = int.Parse(row["visit_count"].ToString());
            string visit_type;

            //Add a URL to list URLs
            URLs.Add(new URL(url, title, browser, visited, frequency));

            // Add entry to list
            //    URLs.Add(u);
            if (title != "")
            {
                Console.WriteLine(String.Format("{0} {1}", title, browser));
            }
        }
    }

    return URLs;
}



DataTable ExtractFromTable(string table, string folder)
{
    SQLiteConnection sql_con;
    SQLiteCommand sql_cmd;
    SQLiteDataAdapter DB;
    DataTable DT = new DataTable();

    // FireFox database file
    string dbPath = folder + "\\places.sqlite";

    // If file exists
    if (File.Exists(dbPath))
    {
        // Data connection
        sql_con = new SQLiteConnection("Data Source=" + dbPath +
                            ";Version=3;New=False;Compress=True;");

        // Open the Connection
        sql_con.Open();
        sql_cmd = sql_con.CreateCommand();

        // Select Query
        string CommandText = "select * from " + table;

        // Populate Data Table
        DB = new SQLiteDataAdapter(CommandText, sql_con);
        DB.Fill(DT);

        // Clean up
        sql_con.Close();
    }
    return DT;
}

现在,我该如何优化这些以使它们更快?

【问题讨论】:

  • 您是否考虑过让数据库为您进行连接?

标签: c# sqlite select


【解决方案1】:

确保您最近运行过 SQL 命令“ANALYZE {db|table|index};”。

我最近遇到了一种情况,即在我的 ER 软件 (Navicat) 中查询运行速度很快(1 分钟)。事实证明,因为我在 Navicat (SQLite v3.7) 中进行了数据库设计,所以统计数据与 Visual Studio (v3.8) 中的 System.Data.SQLite 使用的统计数据不同。运行“分析;”在 Visual Studio 的整个数据库文件上更新了 v3.8 使用的 [sqlite_statX] 表。之后两个地方的速度一样。

【讨论】:

    【解决方案2】:

    除了将更多的数据聚合作为连接移至 SQL 之外,您还可以考虑让您的 SQLiteDataReader 提供数据类型,而不是总是解析值。

    例如,你有一行:

    long visitlong = Int64.Parse(dr[5].ToString());
    

    dr[5] 是一个 Sqlite 值,您首先将其转换为字符串,然后将其解析为 long。这些解析操作需要时间。为什么不这样做:

    long visitlong = dr.GetInt64(5);
    

    或者:

    long visitlong = dr.GetInt64(dr.GetOrdinal("columnName"));
    

    查看the various methods that SqliteDataReader offers 并尽可能利用它们而不是解析值。

    编辑:

    请注意,这需要将数据存储为正确的类型。如果数据库中的所有内容都存储为字符串,那么一些解析将是不可避免的。

    【讨论】:

    • 谢谢,但是我发现我的问题是,当我用调试运行它时,它很慢,但是当我在不调试的情况下运行它时,它会在几秒钟内完成。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多