Если я останавливаю длительный запрос, он откатывает?

Вы можете поместить некоторые инструкции Java в цикл для инициализации коллекции:

List characters = new ArrayList() {
    {
        for (char c = 'A'; c <= 'E'; c++) add(c);
    }
};

Random rnd = new Random();

List integers = new ArrayList() {
    {
         while (size() < 10) add(rnd.nextInt(1_000_000));
    }
};

Но этот случай влияет на производительность, проверьте это обсуждение

25
задан Brian Tompsett - 汤莱恩 1 July 2015 в 12:26
поделиться

10 ответов

нет, SQL-сервер не будет откатывать удаление, это уже работало при остановке выполнения запросов. оракул требует явной поддержки запросов действия, или данные откатываются, но не mssql.

с SQL-сервером это не будет откатывать, если Вы не будете конкретно работать в контексте транзакции, и Вы откатываете ту транзакцию или завершения соединения без фиксировавшей транзакции. но я не вижу контекст транзакции в Вашем выше запроса.

Вы могли также попытаться реструктурировать свой запрос для создания удаления немного более эффективного, но по существу если спецификации поля не на должном уровне тогда, Вы могли бы застрять, переждав его.

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

28
ответ дан user10635 28 November 2019 в 21:14
поделиться

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

я конкретно протестировал это сам на моем собственном SQL Server с помощью следующего запроса, и таблица ApplicationLog была пуста даже при том, что я отменил запрос:

declare @count int
select @count = 5
WHILE @count > 0
BEGIN
  print @count
  delete from applicationlog;
  waitfor time '20:00';
  select @count = @count -1
END

Однако Ваш запрос, вероятно, займет много дней или недель, намного дольше тогда 15 часов. Ваша оценка, что можно обработать 2 000 записей каждые 6 секунд, является неправильной, потому что каждое повторение в цикле с условием продолжения возьмет значительно дольше с 17 миллионами строк тогда, это делает с 2 000 строк. Таким образом, если Ваш запрос не занимает значительно меньше тогда секунду для 2 000 строк, потребуются дни для всех 17 миллионов.

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

8
ответ дан jwanagel 28 November 2019 в 21:14
поделиться

Если Вы не сделаете ничего явного о транзакциях тогда, то соединение будет в транзакции автоматической фиксации режим. В этом режиме каждый SQL-оператор считают транзакцией.

вопрос состоит в том, означает ли это, что отдельные SQL-операторы являются транзакциями и поэтому фиксируются, когда Вы идете, или рассчитывает ли внешний Цикл с условием продолжения как транзакция.

, кажется, нет никакого обсуждения этого в описании В ТО ВРЕМЯ КАК конструкция на MSDN. Однако, так как НЕКОТОРОЕ ВРЕМЯ оператор не может непосредственно изменить базу данных, казалось бы логичным, что это не делает , запускают транзакцию автоматической фиксации.

2
ответ дан Rob Walker 28 November 2019 в 21:14
поделиться

Неявные транзакции

, Если никакие 'Неявные транзакции' был установлен, то каждое повторение в Вашем цикле фиксировало изменения.

для любого SQL Server возможно быть установленным с 'Неявными транзакциями'. Это - установка базы данных (по умолчанию ВЫКЛЮЧЕНО). У Вас могут также быть неявные транзакции в свойствах особого запроса в Studio управления (щелчок правой кнопкой в области запроса> опции) настройками по умолчанию в клиенте или оператором SET.

SET IMPLICIT_TRANSACTIONS ON;

Так или иначе, если бы это имело место, необходимо было бы все еще выполнить явную ФИКСАЦИЮ/ОТКАТ независимо от прерывания выполнения запросов.

<час>

ссылка Неявных транзакций:

http://msdn.microsoft.com/en-us/library/ms188317.aspx

http://msdn.microsoft.com/en-us/library/ms190230.aspx

2
ответ дан Ricardo C 28 November 2019 в 21:14
поделиться

Я наследовал систему, которая имела логику, которую что-то как Ваш реализовало в SQL. В нашем случае мы пытались соединить строки с помощью нечеткого соответствия, которое имело подобные имена/адреса, и т.д., и что логика была сделана просто в SQL. В то время, когда я наследовал его, у нас было приблизительно 300 000 строк в таблице и согласно синхронизациям, мы вычислили, потребуется ГОД для соответствия им всем.

Как эксперимент для наблюдения, насколько быстрее я мог сделать это за пределами SQL я записал программу, чтобы вывести таблицу базы данных в плоские файлы, считать плоские файлы в программу C++, создать мои собственные индексы, и сделать нечеткую логику там, затем повторно импортировать плоские файлы в базу данных. То, что заняло ГОД в SQL, заняло приблизительно 30 секунд в приложении C++.

Так, мой совет, даже не пробуют то, что Вы делаете в SQL. Экспорт, процесс, переимпорт.

1
ответ дан Corey Trager 28 November 2019 в 21:14
поделиться

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

, Если Вы не выполняете его явно в транзакции, это будет только откатывать выполняющийся оператор.

0
ответ дан Community 28 November 2019 в 21:14
поделиться

УДАЛЯЕТ, которые были выполнены до этой точки, не будет откатываться.

<час>

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

RecordId лучше быть PRIMARY KEY. Я не имею в виду ИДЕНТИФИКАЦИОННЫХ ДАННЫХ, я имею в виду PRIMARY KEY. Подтвердите этот sp_help

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

SELECT *
FROM MyTable
WHERE @long = longitude
  AND @lat = latitude
  AND @businessname = BusinessName
  AND @phoneNumber = Phone

Прежде и После добавления этого индекса, проверьте план запросов, чтобы видеть, было ли индексное сканирование добавлено.

1
ответ дан Community 28 November 2019 в 21:14
поделиться

Я думаю, что этот запрос был бы намного более эффективным, если бы он был переписан с помощью однопроходного алгоритма с помощью курсора. Вы заказали бы Вам таблицу курсора долготой, широтой, BusinessName И @phoneNumber. You’d ступают через строки по одному. Если строка имеет ту же долготу, широту, businessname, и phonenumber как предыдущая строка, то удалите его.

0
ответ дан Aheho 28 November 2019 в 21:14
поделиться

Я вполне уверен, который является отрицательным. Иначе, какова точка транзакций была бы?

-1
ответ дан Joe Phillips 28 November 2019 в 21:14
поделиться

Я думаю, вам нужно серьезно подумать о своей методологии. Вам нужно начать думать наборами (хотя для повышения производительности вам может потребоваться пакетная обработка, но не построчно для таблицы из 17 миллионов записей).

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

Что-то вроде (Примечание. t написать статус создания индекса, я полагаю, вы можете найти это сами):

SELECT min(m.RecordID), m.longitude, m.latitude, m.businessname, m.phone  
     into  #RecordsToKeep    
FROM MyTable   m
join 
(select longitude, latitude, businessname, phone
from MyTable
group by longitude, latitude, businessname, phone
having count(*) >1) a 
on a.longitude = m.longitude and a.latitude = m.latitude and
a.businessname = b.businessname and a.phone = b.phone 
group by  m.longitude, m.latitude, m.businessname, m.phone   
ORDER BY CASE WHEN m.webAddress is not null THEN 1 ELSE 2 END,        
    CASE WHEN m.caption1 is not null THEN 1 ELSE 2 END,        
    CASE WHEN m.caption2 is not null THEN 1 ELSE 2 END



while (select count(*) from #RecordsToKeep) > 0
begin
select top 1000 * 
into #Batch
from #RecordsToKeep

Delete m
from mytable m
join #Batch b 
        on b.longitude = m.longitude and b.latitude = m.latitude and
        b.businessname = b.businessname and b.phone = b.phone 
where r.recordid <> b.recordID

Delete r
from  #RecordsToKeep r
join #Batch b on r.recordid = b.recordid

end

Delete m
from mytable m
join #RecordsToKeep r 
        on r.longitude = m.longitude and r.latitude = m.latitude and
        r.businessname = b.businessname and r.phone = b.phone 
where r.recordid <> m.recordID
0
ответ дан 28 November 2019 в 21:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: