Выполненный jps -lv
, который показывает PIDs и командные строки всех рабочих процессов Java.
Определяют PID задачи, которую Вы хотите уничтожить. Тогда используйте команду:
taskkill /PID <pid>
для уничтожения процесса неправильного поведения.
Когда механизм запросов видит это ...
(SELECT TOP 1 [val] FROM @randomStuff ORDER BY NEWID())
... это все похоже на «ооооо, кэшируемый скалярный подзапрос, я собираюсь кэшировать это!»
Вам нужно обмануть механизм запросов, заставив его думать, что он не кэшируемый. Ответ jfar был близок, но обработчик запросов был достаточно умен, чтобы увидеть тавтологию MyTable.MyColumn = MyTable.MyColumn
, но он недостаточно умен, чтобы увидеть это.
UPDATE MyTable
SET MyColumn = (SELECT TOP 1 val
FROM @randomStuff r
INNER JOIN MyTable _MT
ON M.Id = _MT.Id
ORDER BY NEWID())
FROM MyTable M
Добавляя внешнюю таблицу (MT) в подзапрос, механизм запросов предполагает, что подзапрос необходимо будет повторно оценить. На самом деле все будет работать, но я выбрал (предполагаемый) первичный ключ MyTable.Id, поскольку он будет проиндексирован и добавит очень мало накладных расходов.
Курсор, вероятно, будет таким же быстрым, но определенно не таким весело.
использовать перекрестное соединение для генерации случайных данных
У меня нет времени проверять это прямо сейчас, но мое чутье подсказывает мне, что если бы вы создали функцию на сервере для получения случайного значения, это не помогло бы ее оптимизировать. .
тогда у вас будет
UPDATE MyTable
Set MyColumn = dbo.RANDOM_VALUE()
Здесь не происходит оптимизации.
Вы используете подзапрос, который выбирает одно значение, оптимизировать нечего.
Вы также можете попробовать поставить столбец из таблицы, которую вы обновляете, в выберите и посмотрите, изменится ли что-нибудь. Это может вызвать оценку для каждой строки в MyTable
UPDATE MyTable
SET MyColumn = (SELECT TOP 1 [val] FROM @randomStuff ORDER BY NEWID()
WHERE MyTable.MyColumn = MyTable.MyColumn )
Я придумал решение, которое является чем-то вроде взлома и очень неэффективным (10 ~ секунд на обновление 3000 записей). Поскольку это используется для генерации тестовых данных, мне не нужно беспокоиться о скорости.
В этом решении я перебираю каждую строку в таблице и обновляю значения по одной строке за раз. Кажется, это работает:
DECLARE @rows INT
DECLARE @currentRow INT
SELECT @rows = COUNT(*) FROM dbo.MyTable
SET @currentRow = 1
WHILE @currentRow < @rows
BEGIN
UPDATE MyTable
SET MyColumn = (SELECT TOP 1 [val] FROM @randomStuff ORDER BY NEWID())
WHERE MyPrimaryKey = (SELECT b.MyPrimaryKey
FROM(SELECT a.MyPrimaryKey, ROW_NUMBER() OVER (ORDER BY MyPrimaryKey) AS rownumber
FROM MyTable a) AS b
WHERE @currentRow = b.rownumber
)
SET @currentRow = @currentRow + 1
END
Я поигрался с этим и нашел довольно хитрый способ сделать это с использованием промежуточной табличной переменной.
После настройки @randomStuff мы делаем это (обратите внимание, что в моем случае @MyTable - это табличная переменная, настройте ее соответствующим образом для вашей обычной таблицы):
DECLARE @randomMappings TABLE (id INT, val VARCHAR(100), sorter UNIQUEIDENTIFIER)
INSERT INTO @randomMappings
SELECT M.id, val, NEWID() AS sort
FROM @MyTable AS M
CROSS JOIN @randomstuff
так что на данный момент у нас есть промежуточная таблица с каждой комбинацией (mytable id, случайное значение) и случайной сортировкой значение для каждой строки, относящейся к этой комбинации. Then
DELETE others FROM @randomMappings AS others
INNER JOIN @randomMappings AS lower
ON (lower.id = others.id) AND (lower.sorter < others.sorter)
Это старый трюк, который удаляет все строки для данного MyTable.id, кроме строки с меньшим значением сортировки - присоединить таблицу к самой себе, где это значение меньше, и удалить все, где такое соединение было успешным. Это просто оставляет позади самое низкое значение. Итак, для каждого MyTable.id у нас остается только одно (случайное) значение ... Затем мы просто вставляем его обратно в таблицу:
UPDATE @MyTable
SET MyColumn = random.val
FROM @MyTable m, @randomMappings AS random
WHERE (random.id = m.id)
И готово!