SQLite代码优化

本文关键字:代码优化 SQLite | 更新日期: 2023-09-27 18:08:03

我是一个业余程序员,正在编写一个报告工具,从SQLite数据库导出值到Excel。

Excel部分已写入并工作,我从SQLite中检索的数据正在程序中创建块并需要几分钟来处理。

我使用泛型值重写了代码,以帮助说明过程。初始populateList模块花费的时间可以忽略不计,但我在下面包含了它,因为它正在为doStuff模块提供数据。populateList当前检索大约500条不同的记录。

我需要程序遍历populateList检索到的所有值并执行几个计数。然后用计算值填充另一个列表valuesCount

我试图通过在不关闭SQLite连接的情况下循环遍历列表来提高速度,但改进还不够。是否有更有效的方法从数据库中检索这些信息?

public list<string>populateList()
{
List<string>values = new list<string>();
using (SQLiteConnection con = new SQLiteConnection(Passer.connstr))
{
    con.Open();
    string distinctValues = "SELECT DISTINCT '"value list'" FROM valueTable order by '"value list'" ";
    using (SQLiteCommand cmd = new SQLiteCommand(distinctValues, con))
    {
        SQLiteDataReader sqReader;
        sqReader = cmd.ExecuteReader();
        while (sqReader.Read())
        {
            values.Add(sqReader["value list"].ToString());
        }
    }
}
return values;
}
public void doStuff()
{
bool blanks = false;
string singleValue = string.Empty
string query = string.Empty;
List<string> getInitialValues = populateList();
list<string> valuesCount = new list<string>();
    using (SQLiteConnection con = new SQLiteConnection(Passer.connstr))
    {
        con.Open();
        for(int i = 0; i < getInitialValues.Count; i++)
        {
            blanks = false;
            singleValue = getInitialValues[i];
            if(singlevalue == "")
            {
                singleValue = '"'";
                blanks = true;
            }
            for (int x = 0; x < 6; x++)
            {
                string statement = string.Empty;
                switch(x)
                {
                    case 0:
                        statement = "SELECT COUNT(*) from valueTable where '"column1'" = ";
                        break;
                    case 1:
                        statement = "SELECT COUNT(*) from valueTable where '"column2'" = '"condition 1'" and '"column1'" = ";
                        break;
                    case 2:
                        statement = "SELECT COUNT(*) from valueTable where '"column3'" = '"condition 3'" and '"column1'" = ";
                        break;
                    case 3:
                        statement = "SELECT COUNT(*) from valueTable where '"column4'" = '"condition 4'" and '"column1'" = ";
                        break;
                    case 4:
                        statement = "SELECT COUNT(*) from valueTable where '"column5'" = '"condition 5'" and '"column1'" = ";
                        break;
                    case 5:
                        statement = "SELECT COUNT(*) from valueTable where '"column6'" = '"condition 6'" and '"column1'" = ";
                        break;                      
                }
                if (blanks == true)
                {
                    query = System.String.Format("{0}{1}", statement, singleValue);
                }
                else 
                {
                    query = System.string.format("{0}'"{1}'"", statement, singleValue);
                }
                using (SQLiteCommand cmd = new SQLiteCommand(query, con))
                {
                    string countValues = cmd.ExecuteScalar().ToString();
                    valuesCount.Add(countValues);
                }
            }
        }
    }
}

SQLite代码优化

考虑将其写成单个SQL查询。

你正在执行许多查询,当它看起来很像你只需要对列执行一个"条件计数"。SQL将沿着

的行
select 
  val,
  col1 = sum(case when col1 = 'cond1' then 1 end)
from valtbl
group by val

你甚至不需要第一个方法来获取不同值的列表

或者,当表看起来相当小时,选择您需要的"行"列表,并使用Linq to Objects进行计数。

您正在多次查询数据库以获得相同的信息。我建议不要对dostuff方法进行任何db调用,而是使用单个查询来获取有价值的记录。

则可以对列表本身进行计数操作。

例如get
"SELECT 'valueCol' , 'col1', 'col2' from valueTable" 

将是您唯一的查询,您将将其存储在列表中(例如valueList)。

然后在c#端你可以使用
 //not actual code just a sample idea
    var distinctValues = valueList.select(v => w.valueCol).Distinct()
    var count = 0;
    switch(case): 
        case 0:
            count += valueList.where(v => v.col1 == condition).Count();
                break; //and so on...