2015-08-16 2 views
0

Я программист-программист и записываю инструмент для экспорта значений из базы данных SQLite в Excel.Оптимизация кода SQLite

Часть 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); 
       } 
      } 
     } 
    } 
} 

ответ

0

Вы запрашиваете базу данных несколько раз, чтобы получить ту же информацию. Я бы предложил не делать какие-либо вызовы db метода dostuff, вместо этого использовать один запрос для извлечения формы записей valueetable.

Затем вы можете выполнять операции подсчета в самом списке.

Например получить

"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... 
+0

Спасибо SadiRubaiyet, я изменил код вокруг, как вы предложили, и существует значительный прирост производительности. – vectors36

1

Рассмотрите возможность написания его как единого SQL-запроса.

Вы выполняете множество запросов, когда это очень похоже на то, что вам просто нужно выполнить «условный подсчет» для столбцов. SQL будет по строкам

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

0 Вам не нужен даже первый метод получения списка различных значений.

Альтернативно, поскольку таблица кажется достаточно малой, выберите то, что вам нужно, в список «строк» ​​и используйте Linq to Objects для подсчета.

Смежные вопросы