C# SQL Command .Fill занимает слишком много времени при вызове сервера Firebird, присоединяется к таблице с хранимой процедурой
Я пытаюсь сбросить данные из базы данных Firebird SQL 2.5 с небольшим успехом или безуспешно, потому что я пытаюсь объединить таблицу и хранимую процедуру. Код, представляющий проблемный запрос, следующий:
select
U.SYMBOL
, '0' AS FIRM_ID
, U.DATA_OD AS DATA
, IIF(EXTRACT(DAY FROM U.DATA_OD) = 1 AND EXTRACT(MONTH FROM U.DATA_OD) = 1, 'NR', 'ZW') AS PRZYCZYNA_ZMIANY_WYM
, PS.WYMIAR AS WYMIAR
, PS.ZALEGLY AS WYM_ZAL
, ' ' AS WYMIAR_INW
, ' ' AS WYMIAR_INW_ZAL
, ' ' AS NAZWA_ABSENCJI
from
P_PRA_WYM_URL U
left JOIN PS_WYK_URLOPOW(U.SYMBOL, U.DATA_OD, U.DATA_OD) ps ON 1=1
where
U.SYMBOL IN (SELECT SYMBOL FROM P_PRACOWNIK)
В PS_WYK_URLOPOW
хранимая процедура принимает три параметра: номер сотрудника и две даты. Все параметры являются членамиP_PRA_WYM_URL
table, поэтому хранимая процедура должна выполняться один раз для каждой записи в этой таблице. В этой таблице более 40 000 записей.
Я выполняю этот запрос, используя следующий код C#:
if (AreSettingsPopulated())
{
string sFilepath = dSettings[FILEPATHKEY];
string sUsername = dSettings[USERNAMEKEY];
string sPassword = Encoding.UTF8.GetString(System.Convert.FromBase64String(dSettings[DBPASSWORDKEY]));
string connectionString =
"User={0};" +
"Password={1};" +
"Database={2};" +
"DataSource=localhost;" +
"Port=3050;" +
"Dialect=1;" +
"Charset=NONE;" +
"Role=;" +
"Connection lifetime=15;" +
"Pooling=true;" +
"MinPoolSize=0;" +
"MaxPoolSize=50;" +
"Packet Size=8192;" +
"ServerType=0";
FbConnection fbConn = null;
try
{
string sSqlQuery = "";
using (FileStream fs = new FileStream(string.Format("{0}.sql", dSettings[TABLENAMEKEY]), FileMode.Open))
{
using (StreamReader sr = new StreamReader(fs, Encoding.UTF8))
{
if (!sr.EndOfStream)
sSqlQuery = sr.ReadToEnd();
sr.Close();
}
fs.Close();
}
if (sSqlQuery != "")
{
DataTable dtDumpResults = new DataTable(dSettings[TABLENAMEKEY]);
fbConn = new FbConnection(string.Format(connectionString, sUsername, sPassword, sFilepath));
FbCommand fbcDumpCommand = new FbCommand(sSqlQuery, fbConn);
fbcDumpCommand.CommandTimeout = 90000000;
if (fbConn.State != System.Data.ConnectionState.Open)
fbConn.Open();
using (FbDataAdapter fbdaDumpCommand = new FbDataAdapter(sSqlQuery, fbConn))
{
this.engine.WriteLine("Dumping the contents from database...");
fbdaDumpCommand.Fill(dtDumpResults);
this.engine.WriteLine("Dump complete!");
}
if (dtDumpResults.Rows.Count > 0)
{
GenerateExportXlsFile(dtDumpResults, dSettings[TABLENAMEKEY]);
}
else
throw new ArgumentNullException("The result set returned null!");
}
else
throw new ArgumentNullException("The SQL query is empty!");
}
catch (Exception ex)
{
return string.Format("Error while invoking plugin: {0}", ex.ToString());
}
finally
{
if (fbConn != null && fbConn.State == System.Data.ConnectionState.Open)
fbConn.Close();
}
}
else
return "Execution failed! The settings are not populated!";
return string.Format("Export of table {0} complete!", dSettings[TABLENAMEKEY]);
}
Если я попытаюсь сбросить данные с помощью запроса, показанного выше, с помощью Flamerobin, механизм предварительной выборки будет работать и загружать данные каждые 500 записей, и я могу получить полный дамп, в то время как с приложением C# выполнение останавливается на fbdaDumpCommand.Fill(dtDumpResults);
шаг.
Возникает вопрос: как оптимизировать запрос, чтобы он работал внутри приложения C#?