Лучшая производительность при чтении миллионов записей данных

У меня есть база данных с большим количеством данных (миллионы строк), а также обновление в течение дня с большим количеством данных, у меня есть резервная копия этой базы данных для отчетности, поэтому получение отчета данных не влияет на производительность основной базы данных.

Для синхронизации резервной базы данных с основной базой данных я написал службу Windows, которая запрашивает основную базу данных и вставляет новые данные в резервную базу данных... каждый раз, когда запрос получает 5000 строк из основной базы данных...

РЕДАКТИРОВАТЬ:

запрос выглядит следующим образом:

const string cmdStr = "SELECT * FROM [RLCConvertor].[dbo].[RLCDiffHeader] WHERE ID >= @Start and ID <= @End";

Вот код:

using (var conn = new SqlConnection(_connectionString))
{
            conn.Open();
            var cmd = new SqlCommand(cmdStr, conn);               
            cmd.Parameters.AddWithValue("@Start", start);
            cmd.Parameters.AddWithValue("@End", end);

            SqlDataReader reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess);

            while (reader.Read())
            {
                var rldDiffId = Convert.ToInt32(reader["ID"].ToString());
                var rlcDifHeader = new RLCDiffHeader
                {
                    Tech_head_Type = long.Parse(reader["Tech_head_Type"].ToString()),
                    ItemCode = long.Parse(reader["ItemCode"].ToString()),
                    SessionNumber = long.Parse(reader["SessionNumber"].ToString()),                        
                    MarketFeedCode = reader["MarketFeedCode"].ToString(),
                    MarketPlaceCode = reader["MarketPlaceCode"].ToString(),
                    FinancialMarketCode = reader["FinancialMarketCode"].ToString(),
                    CIDGrc = reader["CIDGrc"].ToString(),
                    InstrumentID = reader["InstrumentID"].ToString(),
                    CValMNE = reader["CValMNE"].ToString(),
                    DEven = reader["DEven"].ToString(),
                    HEven = reader["HEven"].ToString(),
                    MessageCodeType = reader["MessageCodeType"].ToString(),
                    SEQbyINSTandType = reader["SEQbyINSTandType"].ToString()                                            
                };
                newRLCDiffHeaders.Add(rldDiffId, rlcDifHeader);
            }
            conn.Close();
        }

но когда я запустил службу... производительность основной базы данных ухудшилась... код неэффективен? Есть ли лучший способ? Потому что я искал и обнаружил, что dataReader лучше всего подходит для этого случая... или мне следует использовать DataTable и SqlDataAdapter?


person Paridokht    schedule 22.10.2013    source источник
comment
Нет, использование SqlDataAdapter определенно не является более эффективным способом работы. Единственное, что я бы порекомендовал, — попробовать меньший размер... 5000 строк могут привести к тому, что SQL Server выполнит эскалацию блокировок и заблокирует всю таблицу — вместо того, чтобы блокировать строки. уровневые замки. Используйте 2000 строк или что-то в этом роде.   -  person marc_s    schedule 22.10.2013
comment
Кроме того, вы смотрели на репликацию SQL Server, которая будет выполнять все это для вас - и это прямо в продукте, настроенном на максимальную производительность ....   -  person marc_s    schedule 22.10.2013
comment
Для производительности базы данных ваши запросы, отправленные в базу данных, более важны, чем использование DataTable или DataReader. Вы можете прочитать незафиксированные данные с помощью ключевого слова nolock.   -  person mehmet mecek    schedule 22.10.2013
comment
Для меня самой интересной частью этого вопроса было бы содержимое cmdStr - без этого все, что у нас есть, это код, который считывается из устройства чтения данных - это само по себе нормально и не является неэффективным. Но: какую команду вы используете и как часто вы ее запускаете? Мое предположение заключается в том, что любая потеря производительности здесь связана со временем, проведенным на сервере БД — но вы должны профилировать это, чтобы выяснить это — там нет ничего, что указывало бы на производительность .NET. проблема   -  person Marc Gravell    schedule 22.10.2013
comment
@Marc GravellДа, да .. правильно, я только что отредактировал свой вопрос .. но запрос простой .. это просто выбор с предложением where.   -  person Paridokht    schedule 22.10.2013
comment
@Mecek, не могли бы вы объяснить, что вы можете больше читать незафиксированные данные с помощью ключевого слова nolock ?? как я уже сказал выше, запрос прост ... просто выберите с предложением where.   -  person Paridokht    schedule 22.10.2013
comment
@Paridokht, есть ли кластеризованный индекс на ID? Что касается nolock - это будет: SELECT * FROM [RLCConvertor].[dbo].[RLCDiffHeader] with (nolock) WHERE ID >= @Start and ID <= @End - это позволит избежать проблем, если на вас негативно влияет блокировка, но это будет означать, что вы можете выполнять грязное чтение   -  person Marc Gravell    schedule 22.10.2013
comment
@MarcGravell: я только что определил новый индекс для столбца ... Я думаю, что производительность улучшится ... но мне нужно подождать до завтра, чтобы увидеть результат.   -  person Paridokht    schedule 22.10.2013


Ответы (1)


Вы не можете рассматривать это как правильный ответ или решение вашей проблемы. Поскольку комментарий становится большим, я предлагаю вам решение.

Можете ли вы попробовать использовать концепцию Ad hoc запросов

Используя это, вы можете запросить другую базу данных, используя следующий способ

SELECT a.*
FROM OPENROWSET('SQLNCLI', 'Server=Seattle1;Trusted_Connection=yes;',
     'SELECT GroupName, Name, DepartmentID
      FROM AdventureWorks2012.HumanResources.Department
      ORDER BY GroupName, Name') AS a;

Подробнее http://technet.microsoft.com/en-us/library/ms187569.aspx http://technet.microsoft.com/en-us/library/ms190312.aspx

Поскольку вы используете службу, учетная запись службы наверняка имеет доступ для чтения основной базы данных и вставки в базу данных отчета. Я предлагаю вам иметь SP в вашей базе данных отчетов, который может получить доступ к основной базе данных с помощью OpenRowSet и вставить в нее.

Запрос будет похож на этот.

Insert into tbl
SELECT a.*
    FROM OPENROWSET('SQLNCLI', 'Server=Seattle1;Trusted_Connection=yes;',
         'SELECT GroupName, Name, DepartmentID
          FROM AdventureWorks2012.HumanResources.Department
          ORDER BY GroupName, Name') AS a;

Сформируйте сервис, вам нужно вызвать SP. У нас была похожая проблема, и это было сделано openrowset, и я не знаю, какое влияние это может оказать на производительность. Но я предлагаю вам сделать POC и просто проанализировать его. Еще раз, пожалуйста, рассмотрите это как предложение.

person kbvishnu    schedule 22.10.2013
comment
Спасибо за ваше предложение, я попробую :) - person Paridokht; 22.10.2013
comment
но у меня есть особый метод сохранения, который я должен использовать для сохранения новых данных в базу данных отчета. Я не могу использовать SP для вставки новых данных.. потому что это не поддерживает программирование OOP, я думаю. - person Paridokht; 22.10.2013
comment
что такое ООП программирование? Вы имеете в виду объектно-ориентированное программирование? Покажите способ сохранения. Я думаю, вы используете вещь EF? - person kbvishnu; 22.10.2013
comment
Мне действительно непонятно, почему вы здесь защищаете OPENROWSET - кажется, здесь нет веских аргументов для этого.. - person Marc Gravell; 22.10.2013
comment
@VeeKayBee, я не использую EF, так как вы можете видеть SqlDataReader и Sqlcommand и т. д. ... и я думаю, что метод сохранения не важен, потому что метод сохранения имеет соединение с другой базой данных (база данных отчета) .. the горлышко бутылки - это когда я хочу читать из основной базы данных. - person Paridokht; 22.10.2013
comment
@MarcGravell Мне предложили OPENROWSET, потому что с помощью OPENROWSET мы можем запрашивать базу данных (maindb) с помощью запроса выбора и вставлять записи в другую (reportdb). Наша задача — реплицировать записи в другую БД по условию. Если это возможно с самим SQL-сервером, нам нужен механизм для вызова запроса (выигрышный сервис). - person kbvishnu; 23.10.2013