Загрузка сегментированных данных: записи таблицы в xml - PullRequest
1 голос
/ 18 июля 2011

У меня есть последовательность SQL-запросов, которые приводят к очень большим наборам данных, которые я должен запросить в базе данных и записать их в файлы. У меня около 80 запросов, и каждый из них производит от 1000 до 1000000 записей. Я не могу изменить сами запросы. Я пытаюсь читать 500 000 записей за раз для каждого запроса и записывать в файл. Вот что у меня пока

void WriteXml(string tableName, string queryString)
{
    int pageSize = 500000;
    int currentIndex = 0;
    using (
       SqlConnection connection =
           new SqlConnection(CONNECTION_STRING))
    {
        using (SqlCommand command = new SqlCommand(queryString, connection))
        {
            try
            {
                connection.Open();
                SqlDataAdapter dataAdapter = new SqlDataAdapter(command);
                int rowsRead = 0, count = 0, index = 0;
                do
                {
                    DataSet dataSet = new DataSet("SomeDatasetName");
                    rowsRead = dataAdapter.Fill(dataSet, currentIndex, pageSize, tableName);
                    currentIndex += rowsRead;
                    if (dataSet.Tables.Count > 0 && rowsRead > 0)
                    {
                        dataSet.Tables[0].WriteXml(string.Format(@"OutputXml\{0}_{1}.xml", tableName, index++),
                                                   XmlWriteMode.WriteSchema);
                    }
                }
                while (rowsRead > 0);

            }
            catch (Exception e)
            {
                Log(e);
            }
        }
    }
}

Это работает, но очень-очень медленно. Я почти уверен, что делаю что-то не так здесь, потому что, когда я запускаю это, приложение забирает большую часть моей памяти (у меня есть 6 ГБ), и это требует вечной работы. Я начал его прошлой ночью, и он все еще работает. Я понимаю, что имею дело со многими записями, но не думаю, что это заняло бы столько часов.

Является ли это правильным способом считывания постраничных / сегментированных данных из базы данных? Есть ли способ, которым этот метод может быть оптимизирован или есть другой способ, которым я могу подойти к этому?

Дайте мне знать, если мне что-то не ясно, и я постараюсь дать разъяснения.

1 Ответ

1 голос
/ 18 июля 2011

Пейджинговые перегрузки для DataAdapter.Fill по-прежнему получают весь набор результатов под обложками.Читайте здесь:

http://msdn.microsoft.com/en-us/library/tx1c9c2f%28vs.71%29.aspx

часть, относящаяся к вашему вопросу:

DataAdapter предоставляет возможность возврата только страницы данных через перегрузкиметода Fill.Однако это может быть не лучшим выбором для постраничного просмотра больших результатов запроса, поскольку, хотя DataAdapter заполняет целевой DataTable или DataSet только запрошенными записями, ресурсы для возврата всего запроса все еще используются.Чтобы вернуть страницу данных из источника данных без использования ресурсов, необходимых для возврата всего запроса, укажите для своего запроса дополнительные критерии, которые уменьшают количество возвращаемых строк только до тех, которые необходимы.

В Linq2Sql естьЭто удобные методы Skip and Take для перемещения по данным.Вы можете свернуть свой собственный, используя параметризованный запрос, созданный для того же.Вот пример, чтобы пропустить 100 и взять 20 строк:

SELECT TOP 20 [t0].[CustomerID], [t0].[CompanyName],
FROM [Customers] AS [t0]
WHERE (NOT (EXISTS(
    SELECT NULL AS [EMPTY]
    FROM (
        SELECT TOP 100 [t1].[CustomerID]
        FROM [Customers] AS [t1]
        WHERE [t1].[City] = @p0
        ORDER BY [t1].[CustomerID]
        ) AS [t2]
    WHERE [t0].[CustomerID] = [t2].[CustomerID]
    ))) AND ([t0].[City] = @p1)
ORDER BY [t0].[CustomerID]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...