Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
 Удаление дубликатов - страшно долго  [new]
pavell450
Member

Откуда:
Сообщений: 13
Здравствуйте, прошу помощи у старших товарищей.
Дано: 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 записей...
Может быть надо что-то настроить на сервере, в структуре БД? Индекс создать...
Или нужно переписать запрос полностью, революционно?
Заранее признателен всем, кто откликнется.
25 сен 18, 11:29    [21685167]     Ответить | Цитировать Сообщить модератору
 Re: Удаление дубликатов - страшно долго  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6801
pavell450,

если не брать в расчёт сам запрос, то FK много на эту таблицу?
25 сен 18, 11:31    [21685170]     Ответить | Цитировать Сообщить модератору
 Re: Удаление дубликатов - страшно долго  [new]
KRS544
Member

Откуда:
Сообщений: 497
скопируйте нужные данные в новую таблицу, потом переименуйте.
25 сен 18, 11:31    [21685171]     Ответить | Цитировать Сообщить модератору
 Re: Удаление дубликатов - страшно долго  [new]
komrad
Member

Откуда:
Сообщений: 5245
pavell450,

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

exec sp_spaceused MATERIAL
exec sp_helpindex MATERIAL
25 сен 18, 11:38    [21685176]     Ответить | Цитировать Сообщить модератору
 Re: Удаление дубликатов - страшно долго  [new]
pavell450
Member

Откуда:
Сообщений: 13
TaPaK,
FK не очень много, но полагаю причина задержек не в удалении записей.
Запрос 10ти самых тяжелых запросов пишет про 1 643 789 196 логических считываний при 3771 записях.
Время CPU 83 154 070
Разработчик говорит, что есть еще одна подчиненная таблица.
25 сен 18, 11:39    [21685180]     Ответить | Цитировать Сообщить модератору
 Re: Удаление дубликатов - страшно долго  [new]
pavell450
Member

Откуда:
Сообщений: 13
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
25 сен 18, 11:43    [21685193]     Ответить | Цитировать Сообщить модератору
 Re: Удаление дубликатов - страшно долго  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6801
pavell450
TaPaK,
FK не очень много, но полагаю причина задержек не в удалении записей.
Запрос 10ти самых тяжелых запросов пишет про 1 643 789 196 логических считываний при 3771 записях.
Время CPU 83 154 070
Разработчик говорит, что есть еще одна подчиненная таблица.

или создавать индекс в таблицах с FK на поле REFERECE MATERIALID? или удалять(хотя совет так себе :))
25 сен 18, 11:44    [21685196]     Ответить | Цитировать Сообщить модератору
 Re: Удаление дубликатов - страшно долго  [new]
komrad
Member

Откуда:
Сообщений: 5245
pavell450,

а это ?

select name 
from sys.objects 
where type ='TR'
and parent_object_id=object_id('MATERIAL')

exec sp_depends MATERIAL 
25 сен 18, 11:55    [21685223]     Ответить | Цитировать Сообщить модератору
 Re: Удаление дубликатов - страшно долго  [new]
komrad
Member

Откуда:
Сообщений: 5245
pavell450
TaPaK,
FK не очень много, но полагаю причина задержек не в удалении записей.


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

http://whoisactive.com/downloads/
25 сен 18, 11:57    [21685225]     Ответить | Цитировать Сообщить модератору
 Re: Удаление дубликатов - страшно долго  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6801
komrad
pavell450
TaPaK,
FK не очень много, но полагаю причина задержек не в удалении записей.


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

http://whoisactive.com/downloads/


1 643 789 196 логических считываний. Это сканы таблиц с FK, может там ещё и индексированные представляния... Ну и да наличие триггера.
25 сен 18, 11:58    [21685230]     Ответить | Цитировать Сообщить модератору
 Re: Удаление дубликатов - страшно долго  [new]
pavell450
Member

Откуда:
Сообщений: 13
komrad,


name
trigger_unique_item_code_material

name
dbo.trigger_unique_item_code_material
25 сен 18, 13:04    [21685339]     Ответить | Цитировать Сообщить модератору
 Re: Удаление дубликатов - страшно долго  [new]
invm
Member

Откуда: Москва
Сообщений: 9350
pavell450
Таблица MATERIAL содержит 75 933 записей
Выборка SELECT min(MATERIALID) as ID FROM MATERIAL GROUP BY RATE, TITLE , RESCODE
дает 43 228 записей.
Это копейки.

Покажите план запроса в формате sqlplan. Тогда не придется гадать, что там у вас творится при выполнении.
25 сен 18, 13:26    [21685382]     Ответить | Цитировать Сообщить модератору
 Re: Удаление дубликатов - страшно долго  [new]
pavell450
Member

Откуда:
Сообщений: 13
TaPaK,
Проверка ничего не показала.
Оно и понятно - система пока не под нагрузкой. Пользователей нет, запросов нет.
25 сен 18, 13:34    [21685394]     Ответить | Цитировать Сообщить модератору
 Re: Удаление дубликатов - страшно долго  [new]
komrad
Member

Откуда:
Сообщений: 5245
pavell450
komrad,


name
trigger_unique_item_code_material

name
dbo.trigger_unique_item_code_material


покажите текст этого триггера
25 сен 18, 13:40    [21685407]     Ответить | Цитировать Сообщить модератору
 Re: Удаление дубликатов - страшно долго  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6801
pavell450
TaPaK,
Проверка ничего не показала.
Оно и понятно - система пока не под нагрузкой. Пользователей нет, запросов нет.

а что вы проверяли?
25 сен 18, 13:41    [21685408]     Ответить | Цитировать Сообщить модератору
 Re: Удаление дубликатов - страшно долго  [new]
лолл
Member

Откуда:
Сообщений: 450
pavell450
komrad,


name
trigger_unique_item_code_material

name
dbo.trigger_unique_item_code_material


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;
?
25 сен 18, 13:53    [21685427]     Ответить | Цитировать Сообщить модератору
 Re: Удаление дубликатов - страшно долго  [new]
aleks222
Member

Откуда:
Сообщений: 985
pavell450
Запрос
DELETE FROM MATERIAL WHERE MATERIALID NOT IN ( SELECT min(MATERIALID) as ID FROM MATERIAL GROUP BY RATE, TITLE , RESCODE )
Выполняется 6-10 часов...

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

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 )

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

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 );
25 сен 18, 14:33    [21685483]     Ответить | Цитировать Сообщить модератору
 Re: Удаление дубликатов - страшно долго  [new]
pavell450
Member

Откуда:
Сообщений: 13
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
25 сен 18, 16:27    [21685665]     Ответить | Цитировать Сообщить модератору
 Re: Удаление дубликатов - страшно долго  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6801
Дальше FOR INSERT ,UPDATE лучше не читать
25 сен 18, 16:29    [21685667]     Ответить | Цитировать Сообщить модератору
 Re: Удаление дубликатов - страшно долго  [new]
pavell450
Member

Откуда:
Сообщений: 13
TaPaK,
Был запрос "проверьте, может с таблицей работают другие сессии http://whoisactive.com/downloads/ "
= проверка показала, что других сессий нет
25 сен 18, 16:30    [21685670]     Ответить | Цитировать Сообщить модератору
 Re: Удаление дубликатов - страшно долго  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6801
pavell450
TaPaK,
Был запрос "проверьте, может с таблицей работают другие сессии http://whoisactive.com/downloads/ "
= проверка показала, что других сессий нет

давайте план, уже ж сказали.
25 сен 18, 16:31    [21685673]     Ответить | Цитировать Сообщить модератору
 Re: Удаление дубликатов - страшно долго  [new]
pavell450
Member

Откуда:
Сообщений: 13
aleks222
Вам, батенька, в управдомы надоть переквалифицироваться.

Примерно так и есть, ибо - не разработчик, поддержка, смотрю на черный-черный ящик сбоку, из SQL.
Спасибо за пример скрипта, попробую убедить творцов, что есть иные способы удаления дубликатов ...
25 сен 18, 16:40    [21685695]     Ответить | Цитировать Сообщить модератору
 Re: Удаление дубликатов - страшно долго  [new]
pavell450
Member

Откуда:
Сообщений: 13
TaPaK,

План найти пока не могу, как будто нет такого запроса.
Внутрь системы доступа нет.
25 сен 18, 16:58    [21685728]     Ответить | Цитировать Сообщить модератору
 Re: Удаление дубликатов - страшно долго  [new]
invm
Member

Откуда: Москва
Сообщений: 9350
pavell450
План найти пока не могу,
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
Спасибо за пример скрипта
В основном там бред написан.

Как удалить за один проход по таблице:
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 приводила к таким проблемам.
В общем, план нужен. Иначе можно много чего напредполагать.
25 сен 18, 18:17    [21685818]     Ответить | Цитировать Сообщить модератору
 Re: Удаление дубликатов - страшно долго  [new]
aleks222
Member

Откуда:
Сообщений: 985
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;


Откровение Иоанна-программизда?
Сортировать и нумеровать ВСЕ записи внезапно стало быстрее?
О темпора, о морес!
25 сен 18, 18:58    [21685855]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить