2012-01-18 1 views
0

Итак, у меня есть огромный запрос, который мне нужно запустить в базе данных доступа. Я пытаюсь использовать цикл for, чтобы его сломать, потому что я не могу запустить запрос сразу (у него есть IN с 50 k значениями). Читатель вызывает всевозможные проблемы, висящие и такие. В большинстве случаев, когда я разбиваю цикл for на 50-10000 значений, читатель будет считывать 400 (ровно 400) значений, а затем висеть в течение примерно 3 минут, а затем делать сто или около того, зависать, бесконечно. Если я делаю более 10 тыс. Значений для каждого запроса, он добирается до 2696, а затем зависает, делает еще 1 тыс. Или около того после зависания, вкл. И далее. Я никогда не работал с odbc, sql или любой базой данных, так что это должно быть что-то глупое, или это ожидается? Может быть, есть лучший способ сделать что-то подобное? Вот мой код, который зацикливается:ODBCDataReader случайно висит?

//connect to mdb 
OdbcConnection mdbConn = new OdbcConnection(); 
mdbConn.ConnectionString = @"Driver={Microsoft Access Driver (*.mdb)};DBQ=C:\PINAL_IMAGES.mdb;"; 
mdbConn.Open(); 

OdbcCommand mdbCmd = mdbConn.CreateCommand(); 
mdbCmd.CommandText = @"SELECT RAW_NAME,B FROM 026_006_886 WHERE (B='CM1' OR B='CM2') AND MERGEDNAME IN" + imageChunk; 
OdbcDataReader mdbReader = mdbCmd.ExecuteReader(); 

while (mdbReader.Read()) 
{ 
    sw.WriteLine(@"for /R %%j in (" + mdbReader[0] + @") do move %%~nj.tif .\" + mdbReader[1] + @"\done"); 
    linesRead++; 
    Console.WriteLine(linesRead); 
} 
mdbConn.Close(); 

Вот как я заполнить переменную imageChunk для IN путем считывания 5000 строк со значением строки из текстового файла с помощью StreamReader:

   string imageChunk = "("; 
       for (int j = 0; j < 5000; j++) 
       { 
        string image; 
        if ((image = sr.ReadLine()) != null) 
        { 
         imageChunk += @"'" + sr.ReadLine() + @"',"; 
        } 
        else 
        { 
         break; 
        } 
       } 
       imageChunk = imageChunk.Substring(0, imageChunk.Length - 1); 
       imageChunk += ")"; 
+0

Почему у вас есть IN с 50K значениями? Почему это не в таблице? – Fionnuala

+0

Потому что я ноот! Вы имеете в виду DataTable? – stereotypeaura

+0

Нет, я нет. Я имею в виду таблицу в Access. Это просто неразумно использовать IN для стольких значений. Вам нужно присоединиться к столу. – Fionnuala

ответ

0

Закончен с использованием адаптера данных ... Был медленным, но обеспечивал постоянную обратную связь, а не замерзание. Никогда не получал хороший ответ, почему, но получил несколько советов по более разумным способам выполнения большого запроса.

+0

Ваша медлительность, вероятно, имеет больше общего с неэффективным запросом, чем неэффективный адаптер (или много записей). Разумно ожидать, что 50 тыс. Значений займет меньше минуты, чтобы полностью вернуться. Прежде чем вы ставите свой запрос в код, обычно рекомендуется попробовать запрос непосредственно против данных - я не уверен, как вы это сделаете, но в SQL можно использовать SQL Management Studio для проверки запроса. – EtherDragon

0

Ваше подключение к DB и выполнение запросов кажутся мне обойденными. Я подозреваю, что «зависание» идет, потому что вы выполняете запрос несколько раз. Несколько советов по скорости. Столбцы B и MergedName должны иметь индексы на них. Повторная факторизация структуры таблицы данных также может повысить скорость. Вы объединены с именами по-настоящему случайными? Если это так, вы, вероятно, застряли в скорости, которую у вас есть. Как предлагает @Remou, я бы также сравнил общую продолжительность загрузки вашего списка MergedNames с таблицей, затем присоединился к таблице, чтобы получить ваши результаты, а затем удалите таблицу при завершении.

+0

Если запрос нужно запустить более одного раза, лучше удалить записи, чем удалить таблицу. – Fionnuala