powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Удаление дубликатов - страшно долго
43 сообщений из 43, показаны все 2 страниц
Удаление дубликатов - страшно долго
    #39707531
pavell450
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Здравствуйте, прошу помощи у старших товарищей.
Дано: MS SQL Server 2014
Запрос
DELETE FROM MATERIAL WHERE MATERIALID NOT IN ( SELECT min(MATERIALID) as ID FROM MATERIAL GROUP BY RATE, TITLE , RESCODE )
Выполняется 6-10 часов...

Таблица MATERIAL содержит 75 933 записей
Выборка SELECT min(MATERIALID) as ID FROM MATERIAL GROUP BY RATE, TITLE , RESCODE
дает 43 228 записей.
Индекс в таблице MATERIAL один - MATERIALID

Вопрос знатокам:
Корректен ли такой запрос для удаления дубликатов?
за 10 часов удалено 3600 записей...
Может быть надо что-то настроить на сервере, в структуре БД? Индекс создать...
Или нужно переписать запрос полностью, революционно?
Заранее признателен всем, кто откликнется.
...
Рейтинг: 0 / 0
Удаление дубликатов - страшно долго
    #39707532
TaPaK
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
pavell450,

если не брать в расчёт сам запрос, то FK много на эту таблицу?
...
Рейтинг: 0 / 0
Удаление дубликатов - страшно долго
    #39707533
KRS544
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
скопируйте нужные данные в новую таблицу, потом переименуйте.
...
Рейтинг: 0 / 0
Удаление дубликатов - страшно долго
    #39707535
Фотография komrad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
pavell450,

выполните в базе и покажите результат:

Код: sql
1.
2.
exec sp_spaceused MATERIAL
exec sp_helpindex MATERIAL
...
Рейтинг: 0 / 0
Удаление дубликатов - страшно долго
    #39707537
pavell450
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
TaPaK,
FK не очень много, но полагаю причина задержек не в удалении записей.
Запрос 10ти самых тяжелых запросов пишет про 1 643 789 196 логических считываний при 3771 записях.
Время CPU 83 154 070
Разработчик говорит, что есть еще одна подчиненная таблица.
...
Рейтинг: 0 / 0
Удаление дубликатов - страшно долго
    #39707545
pavell450
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
komrad,
name rows reserved data index_size unused
MATERIAL 89433 117064 KB 116448 KB 544 KB 72 KB


index_name index_description index_keys
PK__MATERIAL__278B51D51F4E3A40 clustered, unique, primary key located on PRIMARY MATERIALID
...
Рейтинг: 0 / 0
Удаление дубликатов - страшно долго
    #39707547
TaPaK
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
pavell450TaPaK,
FK не очень много, но полагаю причина задержек не в удалении записей.
Запрос 10ти самых тяжелых запросов пишет про 1 643 789 196 логических считываний при 3771 записях.
Время CPU 83 154 070
Разработчик говорит, что есть еще одна подчиненная таблица.
или создавать индекс в таблицах с FK на поле REFERECE MATERIALID? или удалять(хотя совет так себе :))
...
Рейтинг: 0 / 0
Удаление дубликатов - страшно долго
    #39707559
Фотография komrad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
pavell450,

а это ?

Код: sql
1.
2.
3.
4.
5.
6.
select name 
from sys.objects 
where type ='TR'
and parent_object_id=object_id('MATERIAL')

exec sp_depends MATERIAL 
...
Рейтинг: 0 / 0
Удаление дубликатов - страшно долго
    #39707560
Фотография komrad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
pavell450TaPaK,
FK не очень много, но полагаю причина задержек не в удалении записей.


проверьте, может с таблицей работают другие сессии

http://whoisactive.com/downloads/
...
Рейтинг: 0 / 0
Удаление дубликатов - страшно долго
    #39707562
TaPaK
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
komradpavell450TaPaK,
FK не очень много, но полагаю причина задержек не в удалении записей.


проверьте, может с таблицей работают другие сессии

http://whoisactive.com/downloads/

1 643 789 196 логических считываний. Это сканы таблиц с FK, может там ещё и индексированные представляния... Ну и да наличие триггера.
...
Рейтинг: 0 / 0
Удаление дубликатов - страшно долго
    #39707631
pavell450
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
komrad,


name
trigger_unique_item_code_material

name
dbo.trigger_unique_item_code_material
...
Рейтинг: 0 / 0
Удаление дубликатов - страшно долго
    #39707653
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
pavell450Таблица MATERIAL содержит 75 933 записей
Выборка SELECT min(MATERIALID) as ID FROM MATERIAL GROUP BY RATE, TITLE , RESCODE
дает 43 228 записей.Это копейки.

Покажите план запроса в формате sqlplan. Тогда не придется гадать, что там у вас творится при выполнении.
...
Рейтинг: 0 / 0
Удаление дубликатов - страшно долго
    #39707661
pavell450
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
TaPaK,
Проверка ничего не показала.
Оно и понятно - система пока не под нагрузкой. Пользователей нет, запросов нет.
...
Рейтинг: 0 / 0
Удаление дубликатов - страшно долго
    #39707671
Фотография komrad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
pavell450komrad,


name
trigger_unique_item_code_material

name
dbo.trigger_unique_item_code_material

покажите текст этого триггера
...
Рейтинг: 0 / 0
Удаление дубликатов - страшно долго
    #39707672
TaPaK
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
pavell450TaPaK,
Проверка ничего не показала.
Оно и понятно - система пока не под нагрузкой. Пользователей нет, запросов нет.
а что вы проверяли?
...
Рейтинг: 0 / 0
Удаление дубликатов - страшно долго
    #39707682
лолл
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
pavell450komrad,


name
trigger_unique_item_code_material

name
dbo.trigger_unique_item_code_material

Код: sql
1.
2.
3.
ALTER TABLE MATERIAL DISABLE TRIGGER dbo.trigger_unique_item_code_material;
DELETE FROM MATERIAL WHERE MATERIALID NOT IN (SELECT min(MATERIALID) as ID FROM MATERIAL GROUP BY RATE, TITLE, RESCODE);
ALTER TABLE MATERIAL ENABLE TRIGGER dbo.trigger_unique_item_code_material;

?
...
Рейтинг: 0 / 0
Удаление дубликатов - страшно долго
    #39707718
aleks222
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
pavell450Запрос
DELETE FROM MATERIAL WHERE MATERIALID NOT IN ( SELECT min(MATERIALID) as ID FROM MATERIAL GROUP BY RATE, TITLE , RESCODE )
Выполняется 6-10 часов...

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

Код: sql
1.
2.
3.
delete t
from MATERIAL as t
WHERE not exists( select * from MATERIAL as t1 where t1.MATERIALID < t.MATERIALID and t1.RATE = t.RATE and t1.TITLE  = t.TITLE  and t1.RESCODE = t.RESCODE )


Особую прыть это проявит, если есть индекс

(RATE, TITLE, RESCODE, MATERIALID )

если же до зарезу хоцца по вашему

Код: sql
1.
2.
3.
create table #IDs (ID int primary key);
insert #IDs with(tablockx) SELECT min(MATERIALID) as ID FROM MATERIAL  GROUP BY RATE, TITLE, RESCODE order by 1;
DELETE FROM MATERIAL WHERE MATERIALID NOT IN ( SELECT  ID FROM #IDs );
...
Рейтинг: 0 / 0
Удаление дубликатов - страшно долго
    #39707830
pavell450
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
komrad,
Текст триггера:

USE [test]
GO
/****** Object: Trigger [dbo].[trigger_unique_item_code_material] Script Date: 9/25/2018 4:24:22 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER trigger [dbo].[trigger_unique_item_code_material] on [dbo].[MATERIAL]

FOR INSERT ,UPDATE
AS

SET NOCOUNT ON;
DECLARE @tempRes VARCHAR(max)
DECLARE @tempId bigint
DECLARE @TempString VARCHAR(max)
DECLARE my_Cursor CURSOR LOCAL FAST_FORWARD FOR SELECT RESCODE,MATERIALID FROM INSERTED;
OPEN my_Cursor
FETCH NEXT FROM my_Cursor into @tempRes,@tempId

WHILE @@FETCH_STATUS = 0

BEGIN
IF ( CHARINDEX( '_N_VALID',@tempRes) = 0)
IF EXISTS ( SELECT before.RESCODE
FROM ( SELECT * FROM dbo.MATERIAL AS a WHERE a.MATERIALID NOT IN(SELECT o.MATERIALID FROM inserted o ) ) AS before
WHERE before.RESCODE=@tempRes )
UPDATE a SET a.RESCODE = a.RESCODE+'_N_VALID' FROM dbo.MATERIAL a WHERE a.MATERIALID = @tempId
FETCH NEXT FROM my_Cursor into @tempRes,@tempId
END
...
Рейтинг: 0 / 0
Удаление дубликатов - страшно долго
    #39707832
TaPaK
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дальше FOR INSERT ,UPDATE лучше не читать
...
Рейтинг: 0 / 0
Удаление дубликатов - страшно долго
    #39707835
pavell450
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
TaPaK,
Был запрос "проверьте, может с таблицей работают другие сессии http://whoisactive.com/downloads/ "
= проверка показала, что других сессий нет
...
Рейтинг: 0 / 0
Удаление дубликатов - страшно долго
    #39707838
TaPaK
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
pavell450TaPaK,
Был запрос "проверьте, может с таблицей работают другие сессии http://whoisactive.com/downloads/ "
= проверка показала, что других сессий нет
давайте план, уже ж сказали.
...
Рейтинг: 0 / 0
Удаление дубликатов - страшно долго
    #39707854
pavell450
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
aleks222Вам, батенька, в управдомы надоть переквалифицироваться.

Примерно так и есть, ибо - не разработчик, поддержка, смотрю на черный-черный ящик сбоку, из SQL.
Спасибо за пример скрипта, попробую убедить творцов, что есть иные способы удаления дубликатов ...
...
Рейтинг: 0 / 0
Удаление дубликатов - страшно долго
    #39707875
pavell450
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
TaPaK,

План найти пока не могу, как будто нет такого запроса.
Внутрь системы доступа нет.
...
Рейтинг: 0 / 0
Удаление дубликатов - страшно долго
    #39707922
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
pavell450План найти пока не могу,
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
select
 t.text, qp.query_plan
from
 sys.dm_exec_query_stats qs cross apply
 sys.dm_exec_query_plan(qs.plan_handle) qp cross apply
 sys.dm_exec_sql_text(qs.sql_handle) t
where
 t.text like N'%DELETE%FROM%MATERIAL%WHERE%MATERIALID%NOT%IN%'
option
 (recompile);


pavell450Спасибо за пример скриптаВ основном там бред написан.

Как удалить за один проход по таблице:
Код: sql
1.
2.
3.
4.
5.
with t as
(
 select row_number() over (partition by RATE, TITLE, RESCODE order by MATERIALID) as rn from MATERIAL
)
delete t where rn > 1;


Если это разовое действие, то можно оставить как есть. Таблица у вас слишком уж маленькая, чтобы показанная форма delete приводила к таким проблемам.
В общем, план нужен. Иначе можно много чего напредполагать.
...
Рейтинг: 0 / 0
Удаление дубликатов - страшно долго
    #39707939
aleks222
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
invmВ основном там бред написан.

Как удалить за один проход по таблице:[src]
with t as
(
select row_number() over (partition by RATE, TITLE, RESCODE order by MATERIALID) as rn from MATERIAL
)
delete t where rn > 1;


Откровение Иоанна-программизда?
Сортировать и нумеровать ВСЕ записи внезапно стало быстрее?
О темпора, о морес!
...
Рейтинг: 0 / 0
Удаление дубликатов - страшно долго
    #39708004
PizzaPizza
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
pavell450Выполняется 6-10 часов...

Таблица MATERIAL содержит 75 933 записей
Выборка SELECT min(MATERIALID) as ID FROM MATERIAL GROUP BY RATE, TITLE , RESCODE
дает 43 228 записей.

Вопрос знатокам:
Корректен ли такой запрос для удаления дубликатов?
за 10 часов удалено 3600 записей...
Может быть надо что-то настроить на сервере, в структуре БД? Индекс создать...
Или нужно переписать запрос полностью, революционно?
Заранее признателен всем, кто откликнется.

Это все не нормально совсем. При том, что сам запрос неэффективный, удаление не должно занимать часы.
Если у вас нет полного доступа к серверу - трогать ничего не рекомендую.
зы. Триггер ваш тоже жуткий.

Без плана запроса нельзя сказать что у вас за проблема. Вставьте SET SHOWPLAN_XML ON; + запрос в SSMS , запросите актуальный план, запустите запрос и прервите если не выполнится сразу. Правой кнопочкой по картинке плана и выбираете XML и постите сюда.

зы. только что понял, что никогда не сталкивался с долгими запросами и не знаю, покажет ли SSMS актуальный план для не выполненного запроса.
...
Рейтинг: 0 / 0
Удаление дубликатов - страшно долго
    #39708007
PizzaPizza
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SELECT [...] FROM MATERIAL WHERE MATERIALID NOT IN ( SELECT min(MATERIALID) as ID FROM MATERIAL GROUP BY RATE, TITLE , RESCODE )
тоже у вас часы выполняется?
...
Рейтинг: 0 / 0
Удаление дубликатов - страшно долго
    #39708011
TaPaK
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PizzaPizzapavell450Выполняется 6-10 часов...

Таблица MATERIAL содержит 75 933 записей
Выборка SELECT min(MATERIALID) as ID FROM MATERIAL GROUP BY RATE, TITLE , RESCODE
дает 43 228 записей.

Вопрос знатокам:
Корректен ли такой запрос для удаления дубликатов?
за 10 часов удалено 3600 записей...
Может быть надо что-то настроить на сервере, в структуре БД? Индекс создать...
Или нужно переписать запрос полностью, революционно?
Заранее признателен всем, кто откликнется.

Это все не нормально совсем. При том, что сам запрос неэффективный, удаление не должно занимать часы.
Если у вас нет полного доступа к серверу - трогать ничего не рекомендую.
зы. Триггер ваш тоже жуткий.

Без плана запроса нельзя сказать что у вас за проблема. Вставьте SET SHOWPLAN_XML ON; + запрос в SSMS , запросите актуальный план, запустите запрос и прервите если не выполнится сразу. Правой кнопочкой по картинке плана и выбираете XML и постите сюда.

зы. только что понял, что никогда не сталкивался с долгими запросами и не знаю, покажет ли SSMS актуальный план для не выполненного запроса.
вот бывает же так, пришёл человек и по полочкам всё разложил, золото.
...
Рейтинг: 0 / 0
Удаление дубликатов - страшно долго
    #39708018
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
aleks222Откровение Иоанна-программизда?
Сортировать и нумеровать ВСЕ записи внезапно стало быстрее?
О темпора, о морес!Дарагуля, видимо ты за своим любимым делом (надувание щек) последние знания растерял.
Может стоило подумать сколько раз твой опус будет полностью сканировать таблицу (индекс)? И чем поможет предложенный индекс?

aleks222
Код: sql
1.
2.
3.
delete t
from MATERIAL as t
WHERE not exists( select * from MATERIAL as t1 where t1.MATERIALID < t.MATERIALID and t1.RATE = t.RATE and t1.TITLE  = t.TITLE  and t1.RESCODE = t.RESCODE )

Не пробовал подумать, что этот запрос поудаляет?

Изучай, может это сподвигнет тебя на освоение матчасти (хотя я очень сильно сомневаюсь):
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
use tempdb;
go

create table dbo.t (id int identity primary key, f1 numeric(18,2), f2 varchar(100), f3 int);

insert into dbo.t
 (f1, f2, f3)
select
 f1, f2, f3
from
 (
  select top (20000)
   rand(checksum(newid())) * 1000, cast(newid() as varchar(100)), rand(checksum(newid())) * 10000
  from
   master.dbo.spt_values a cross join
   master.dbo.spt_values b
 ) t1(f1, f2, f3) cross apply
 (select top (cast(rand(checksum(t1.f1, t1.f2, t1.f3)) * 100 + 1 as int)) Number from master.dbo.spt_values) t2;
go

declare @rows int, @ms int, @dt datetime2, @show_stat bit = 0, @create_index bit = 0, @show_result bit = 0;

declare @result table (description varchar(100), elapsed_time int, rows_deleted int);

/*Индекс, настоятельно рекомендованный aleks222*/
if @create_index = 1
 create index IX_t on dbo.t (f1, f2, f3, id);

/*Супер быстрый запрос от aleks222*/
set @dt = sysdatetime();
begin tran;

if @show_stat = 1 set statistics xml, io on;
delete a
from
 dbo.t a
where
 exists(select 1 from dbo.t b where b.f1 = a.f1 and b.f2 = a.f2 and b.f3 = a.f3 and b.id < a.id)
option
 (maxdop 1);
select @rows = @@rowcount, @ms = datediff(ms, @dt, sysdatetime());
if @show_stat = 1 set statistics xml, io off;

insert into @result values ('Супер быстрый запрос от aleks222', @ms, @rows);
if @show_result = 1 select * from dbo.t order by id;
rollback;

/*Супер медленный запрос от invm*/
set @dt = sysdatetime();
begin tran;

if @show_stat = 1 set statistics xml, io on;
with t as
(
 select row_number() over (partition by f1, f2, f3 order by id) as rn from dbo.t
)
delete t where rn > 1
option
 (maxdop 1);
select @rows = @@rowcount, @ms = datediff(ms, @dt, sysdatetime());
if @show_stat = 1 set statistics xml, io off;

insert into @result values ('Супер медленный запрос от invm', @ms, @rows);
if @show_result = 1 select * from dbo.t order by id;
rollback;

/*Исходный вариант*/
set @dt = sysdatetime();
begin tran;

if @show_stat = 1 set statistics xml, io on;
delete from dbo.t where id not in (select min(id) from dbo.t group by f1, f2, f3) option (maxdop 1);
select @rows = @@rowcount, @ms = datediff(ms, @dt, sysdatetime());
if @show_stat = 1 set statistics xml, io off;

insert into @result values ('Исходный вариант', @ms, @rows);
if @show_result = 1 select * from dbo.t order by id;
rollback;

/*Та-дам!*/
select * from @result order by elapsed_time;
go

drop table dbo.t;
go


Результат без индексаdescriptionelapsed_timerows_deletedСупер медленный запрос от invm3433984746Супер быстрый запрос от aleks2223754984746Исходный вариант5191984746

Результат с индексомdescriptionelapsed_timerows_deletedСупер медленный запрос от invm6391991233Супер быстрый запрос от aleks2226980991233Исходный вариант8976991233
...
Рейтинг: 0 / 0
Удаление дубликатов - страшно долго
    #39708066
Гавриленко Сергей Алексеевич
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Модератор: invm и aleks222, хорош какашками кидаться друг в друга; как дети малые, ей богу.
...
Рейтинг: 0 / 0
Удаление дубликатов - страшно долго
    #39708761
pavell450
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
invm,
Спасибо!
А вот и план запроса
...
Рейтинг: 0 / 0
Удаление дубликатов - страшно долго
    #39708766
pavell450
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
invm,
Спасибо!
А вот и план запроса
...
Рейтинг: 0 / 0
Удаление дубликатов - страшно долго
    #39708809
PizzaPizza
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
pavell450,

"Ну у вас и запросы" - сказала база и повисла

А что такое Table="[ASSEMBLY_MATERIAL]" и какое отношение эта таблица имеет к вашему запросу?
Или же ваша таблица "MATERIAL" вовсе не таблица, а вьюшка и вы из неё удаляете?
...
Рейтинг: 0 / 0
Удаление дубликатов - страшно долго
    #39708821
PizzaPizza
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
pavell450,

Declare @Title nvarchar(max)

@Title = Title

WHERE l.TITLE like @Title"

CONVERT_IMPLICIT(nvarchar(4000),[@Title],0)"

GROUP BY RATE, TITLE


ИМХО группировки и сравнения по nvarchar(4000) или nvarchar(max) = тормоза
...
Рейтинг: 0 / 0
Удаление дубликатов - страшно долго
    #39708838
Glebanski
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
pavell450,

Выберите одного кандидата на удаление указав конкретные значения RATE, TITLE , RESCODE.
и добавьте в условие вашего запроса через AND.
Запустите Profiler и посмотрите, что там ваш запрос вытворяет.
...
Рейтинг: 0 / 0
Удаление дубликатов - страшно долго
    #39708841
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
pavell450А вот и план запросаЖуть кошмарная...
Вы там вместо обработки только строк с "дубликатами" лопатите всю таблицу построчно с жутким апдейтом другой таблицы.

Попробуйте так:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
begin tran;

if object_id('tempdb..#t') is not null
 drop table #t;

create table #t (MATERIALID int primary key, MATERIALID_FIRST int);

with m as
(
 select
  MATERIALID,
  min(MATERIALID) over (partition by RATE, TITLE, RESCODE) as MATERIALID_FIRST,
  count(*) over (partition by RATE, TITLE, RESCODE) as c
 from
  MATERIAL
)
update am
 set
  MATERIALID = m.MATERIALID_FIRST
output
 m.MATERIALID, m.MATERIALID_FIRST into #t
from
 m join
 ASSEMBL_YMATERIAL am on am.MATERIALID = m.MATERIALID
where
 m.c > 1;

delete m
from
 #t t join
 MATERIAL m on m.MATERIALID = t.MATERIALID
where
 t.MATERIALID > t.MATERIALID_FIRST;

commit;
...
Рейтинг: 0 / 0
Удаление дубликатов - страшно долго
    #39708851
Владимир Затуливетер
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
pavell450,

Дополнительно к ответу invm, удостоверьтесь что следующий индекс у вас присутствует на таблице, а то судя по плану его нет.

Код: sql
1.
create index IDX_ASSEMBLY_MATERIAL_MaterialId on dbo.ASSEMBLY_MATERIAL ( MaterialId )
...
Рейтинг: 0 / 0
Удаление дубликатов - страшно долго
    #39708855
Владимир Затуливетер
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Еще вариант

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
create table #tmpMaterialsForDelete ( MaterialId int primary key with (ignore_dup_key = on) );

with cteData
as (
    select *
         , first_value(MaterialId) over (partition by RATE, TITLE, RESCODE order by MaterialId) as MinMaterialId      
    from dbo.MATERIAL
)
update am
set MATERIALID = d.MinMaterialId
    output Deleted.MaterialId into #tmpMaterialsForDelete ( MaterialId )
from dbo.ASSEMBLY_MATERIAL am
    join cteData d on d.MaterialId = am.MaterialId
where am.MATERIALID != d.MinMaterialId

delete from dbo.Material where MaterialId in ( select MaterialId from #tmpMaterialsForDelete )



с тестовыми данными:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
use tempdb
go

create table dbo.Material ( 
    MaterialId int not null primary key
  , RATE int
  , TITLE varchar(128)
  , RESCODE int
);

insert into dbo.Material (MATERIALID, RATE, TITLE, RESCODE)
values
 (1, 1, 'test', 1 ),
 (2, 1, 'test', 1 ),
 (3, 1, 'test2', 1),
 (4, 1, 'test2', 1)
go

create table dbo.ASSEMBLY_MATERIAL (
    Id int identity not null primary key
  , MaterialId int not null
  , SomeData varchar(200) null
)

create index IDX_ASSEMBLY_MATERIAL_MaterialId on dbo.ASSEMBLY_MATERIAL ( MaterialId )
go

insert into dbo.ASSEMBLY_MATERIAL ( MaterialId, SomeData )
values (1, 'a'), (2, 'b'), (3, 'aa'), (4, 'bb'), (4, 'cc')
go

create table #tmpMaterialsForDelete ( MaterialId int primary key with (ignore_dup_key = on) );

with cteData
as (
    select *
         , first_value(MaterialId) over (partition by RATE, TITLE, RESCODE order by MaterialId) as MinMaterialId      
    from dbo.MATERIAL
)
update am
set MATERIALID = d.MinMaterialId
    output Deleted.MaterialId into #tmpMaterialsForDelete ( MaterialId )
from dbo.ASSEMBLY_MATERIAL am
    join cteData d on d.MaterialId = am.MaterialId
where am.MATERIALID != d.MinMaterialId

delete from dbo.Material where MaterialId in ( select MaterialId from #tmpMaterialsForDelete )


select * from dbo.Material
select * from dbo.ASSEMBLY_MATERIAL

go

drop table dbo.Material;
drop table dbo.ASSEMBLY_MATERIAL;
drop table #tmpMaterialsForDelete;
...
Рейтинг: 0 / 0
Удаление дубликатов - страшно долго
    #39708997
pavell450
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
PizzaPizza,
выполняется не часы, быстрее :-)
1:32:29
...
Рейтинг: 0 / 0
Удаление дубликатов - страшно долго
    #39709529
PizzaPizza
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
pavell450PizzaPizza,
выполняется не часы, быстрее :-)
1:32:29

Очень долго для десятков тысяч строк.
Очевидно, где то проблема на стороне дизайна или обслуживания сервера.
Не рекомендую вам вмешиваться в работу сервера если это не ваша зона ответственности - вслепую можно убить базу.
...
Рейтинг: 0 / 0
Удаление дубликатов - страшно долго
    #39709653
TaPaK
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
pavell450,

Assembly_material большая таблица?
...
Рейтинг: 0 / 0
Удаление дубликатов - страшно долго
    #39709838
pavell450
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
TaPaKpavell450,

Assembly_material большая таблица?

165 000 записей
...
Рейтинг: 0 / 0
Удаление дубликатов - страшно долго
    #39709840
TaPaK
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
pavell450TaPaKpavell450,

Assembly_material большая таблица?

165 000 записей
удаление ваших 30к записей рисует 5млрд чтений на эту таблицы, продолжайте развлекаться переписываниями запросов на красивые
...
Рейтинг: 0 / 0
43 сообщений из 43, показаны все 2 страниц
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Удаление дубликатов - страшно долго
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]