Страницы

Поиск по вопросам

воскресенье, 14 апреля 2019 г.

Удаление большого числа строк из таблицы Transact-SQL

В общем нужно удалить из таблицы Nodes порядка 110000 записей, только их id указывается не явно а берётся из другой таблицы.
DELETE FROM Nodes WHERE (id NOT IN (SELECT DISTINCT node_id FROM Relations))
В SELECT DISTINCT id FROM @gh гдето около 20000 записей и в результате удаления не совершаются изза истекшего таймаута.
Update: Если удалять по пакетам и убрать DISTINCT то возникает другая ошибка связанная с нехваткой памяти и завершением процесса SQL Server
WHILE EXISTS(SELECT * FROM Nodes WHERE id NOT IN (SELECT node_id FROM Relations)) DELETE TOP (100) Nodes WHERE id NOT IN (SELECT node_id FROM Relations)


Ответ

На самом деле проблема решена сторонним способом через ADO.NET. Сначала загрузил в список всех id из таблицы Nodes. Затем в другой список загрузил node_id из таблицы Relations. И наконец циклом пробежался по первому списку выполняя запрос на удаление тех строк id которых не содержится во втором списке. Это полностью решает проблему с накоплением памяти. using (var connection = new SqlConnection(MainWindow._connectionString)) { connection.Open(); var readerRelations = new SqlCommand("SELECT DISTINCT node_id FROM Relations", connection).ExecuteReader(); var DistinctRelations = new List(); while (readerRelations.Read()) { DistinctRelations.Add((int)readerRelations.GetValue(0)); } readerRelations.Close();
var readerNodes = new SqlCommand("SELECT id FROM Nodes", connection).ExecuteReader(); var AllNodes = new List(); while (readerNodes.Read()) { AllNodes.Add((int)readerNodes.GetValue(0)); } readerNodes.Close(); int iterator = 0; int NodesCount = AllNodes.Count; int lastpercent = 0; foreach (var node in AllNodes) { int percent = (int)(iterator * 1.0 / NodesCount * 100); if (percent == lastpercent + 1) { lastpercent = percent; DeleteUnnecesseryNodesChanged(this, new MyEventArgs("Удаление ненужных точек", (int)percent)); } if (!DistinctRelations.Contains(node)) { try { new SqlCommand("DELETE FROM Nodes WHERE id = " + node, connection).ExecuteNonQuery(); } catch (Exception e) { var t = e.ToString(); throw new Exception(t); } } iterator++; }
connection.Close(); }

Комментариев нет:

Отправить комментарий