Тайм-ауты с использованием ODBC, но не Openquery для связанного сервера

Я подключаюсь к внешней базе данных через связанный сервер. Я использую многопоточную консольную программу в C# разбить это SELECT заявление.

SELECT * 
FROM (
    SELECT 
        C.Part_Key,
        C.Part_Operation_Key,
        C.Net_Weight,
        C.Plexus_Customer_No,
        C.Serial_No,
        ROW_NUMBER() OVER (ORDER BY C.Serial_No) AS row 
    FROM Part_v_Container AS C
) a
 WHERE a.row > 0 AND a.row <= 1000000

Это работает как чудо, и когда я получаю десять потоков, чтобы получить по 100000 записей каждая, это сокращает время с восьми минут до минуты. Но во время тестирования я сделал только один поток, чтобы получить все 1000000 записей. Основной код выглядит следующим образом:

try
{
    adapter = new OdbcDataAdapter(sqlStatement, connection);
    DataTable dataTable = new DataTable();
    adapter.Fill(dataTable);
    TimeSpan span = (timerStart - DateTime.Now);
    Console.WriteLine("Data collected for thread " + threadNumber + " in the time of " + span);
    timeTest(span);
    Console.WriteLine("Rows collected = " + dataTable.Rows.Count);
    retries = 0;
    dataCollected = true;
}

Опять же, это работает, так что это не проблема. Проблема в том, что я получаю сообщение об ошибке тайм-аута от плекса, когда пытаюсь получить все 1000000 записей:

При извлечении данных из базы данных для потока с номером 0 возникла ошибка. Сообщение об ошибке было следующим: System.Data.Odbc.OdbcException (0x80131937): ОШИБКА [HYT00] [Plex][Драйвер источника данных отчета ODBC ODBC][OpenAccess SDK SQL Engine] Время ожидания запроса истекло [10246] в System.Data.Odbc.OdbcConnection.HandleError(OdbcHandle hrHandle, RetCode retcode) в System.Data.Odbc.OdbcCommand.ExecuteReaderObject(поведение CommandBehavior, метод String, метод SQL объекта, Boolean) odbcApiMethod) в System.Data.Odbc.OdbcCommand.ExecuteReaderObject(поведение CommandBehavior, метод String, логический needReader) в System.Data.Odbc.OdbcCommand.ExecuteReader(поведение CommandBehavior)
в System.Data.Odbc.OdbcCommand.ExecuteDbDataReader(поведение CommandBehavior) в System.Data.Common.DbCommand.System.Data.IDbCommand.ExecuteReader(поведение CommandBehavior) в System.Data.Common.DbDataAdapter.FillTase ] datatables, int32 startRecord, Int32 maxRecords, String srcTable, команда IDbCommand, поведение CommandBehavior) в System.Data.Common.DbDataAdapter.Fill(DataTable[] dataTables, Int32 startRecord, Int32 maxRecords, поведение IDbCommandv at at), CommandB.Common.DbDataAdapter.Fill(DataTable dataTable) в ShippedContainerSettlement.DataCollectionThread.dataCollectionThread() в c:\Users\dkb\Source\Workspaces\ Рабочая область \Danrex\ShippedContainerSettlement\ShippedContainerSettlement FROM (ВЫБРАТЬ C.Part_Key, C.Part_Operation_Key, C.Net_Weight, C.Plexus_Customer_No, C.Serial_No, ROW_NUMBER() OVER (ORDER BY C.Serial_No) КАК строка FROM Part_v_Container AS C) ГДЕ a.row > 0 и a.row <=1005066

Если я выполню этот же запрос в SQL Management Studio, используя openquery, он может собрать все 1000000 записей.

Я понятия не имею, почему, потому что я не очень хорошо разбираюсь в базах данных, поэтому я надеялся, что кто-то может объяснить, почему это может иметь место?

РЕДАКТИРОВАТЬ: Это может быть ответ, который я нашел на этом форуме.

OpenQuery выполняется на сервере, и, возможно, он обрабатывает строки намного быстрее и возвращает только одну строку по сети. Делая это в Visual Studio, вы можете получить полный набор результатов и затем отфильтровать его на принимающем (клиентском) сервере. Это может быть причиной того, что это произошло с Visual Studio, но не с SSMS.

Кажется разумным?

Я только что протестировал openquery в C# и получил тайм-аут даже для таблиц с 3000 записей. Так что на самом деле не уверен, что происходит.

0 ответов

Другие вопросы по тегам