Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Вставить только уникальные значения  [new]
virtuOS
Member

Откуда: большая деревня
Сообщений: 266
Не понимаю, как побороть проблему, иногда (!) ругается на дублирование значений eventid при вставке в таблицу CallBack.
eventid помечено как уникальное в обеих таблицах.

insert into [dbo].[CallBack] (eventid, date_callstart, phone)
	select eventid, date_callstart, phone
	from crm.dbo.call_history H
	where date_callstart >= dateadd(day, -1, getdate())
		and campaign = 'INFORMATION'
		and call_type = 'in'
		and result_ccs <> 'OK'
		and len(phone) = 11
	
		and not exists (
			select 1
			from [dbo].[CallBack] B
			where B.eventid = H.eventid
		)
28 сен 16, 13:16    [19717835]     Ответить | Цитировать Сообщить модератору
 Re: Вставить только уникальные значения  [new]
iljy
Member

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

и что? то, что они уникальные в каждой отдельной таблице, вовсе не означает, что между таблицами они не могут дублироваться.
28 сен 16, 13:22    [19717877]     Ответить | Цитировать Сообщить модератору
 Re: Вставить только уникальные значения  [new]
iap
Member

Откуда: Москва
Сообщений: 47052
virtuOS,

вернёт ли что-нибудь
SELECT eventid, COUNT(*)
FROM crm.dbo.call_history
GROUP BY eventid
HAVING COUNT(*)>1;
?
Если да, то, несмотря на то, что вставляемого eventid в [dbo].[CallBack] ещё нет,
вы пытаетесь сразу вставить более одного одинакового eventid из crm.dbo.call_history.
Надо избавиться от дублей по eventid в результате запроса.
28 сен 16, 13:26    [19717910]     Ответить | Цитировать Сообщить модератору
 Re: Вставить только уникальные значения  [new]
virtuOS
Member

Откуда: большая деревня
Сообщений: 266
iap, ничего не возвращает, eventid действительно уникальны в call_history

Или причина в том, что данные вставляются в таблицу [dbo].[CallBack] и к ней же условие в not exists? Это же бред, по-моему.
28 сен 16, 13:35    [19717985]     Ответить | Цитировать Сообщить модератору
 Re: Вставить только уникальные значения  [new]
iap
Member

Откуда: Москва
Сообщений: 47052
В [dbo].[CallBack] триггер на вставку есть?
28 сен 16, 13:41    [19718032]     Ответить | Цитировать Сообщить модератору
 Re: Вставить только уникальные значения  [new]
virtuOS
Member

Откуда: большая деревня
Сообщений: 266
iap
В [dbo].[CallBack] триггер на вставку есть?

да ничего нет на этой таблице.

Скрипт таблицы
CREATE TABLE [dbo].[CallBack](
	[eventid] [uniqueidentifier] NOT NULL,
	[Stamp] [datetime] NOT NULL CONSTRAINT [DF_CallBack_Stamp]  DEFAULT (getdate()),
	[date_callstart] [datetime] NOT NULL,
	[phone] [varchar](20) NOT NULL,
	[flag_insert] [int] NOT NULL CONSTRAINT [DF_CallBack_flag]  DEFAULT ((0)),
 CONSTRAINT [PK_CallBack] PRIMARY KEY CLUSTERED 
(
	[eventid] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
28 сен 16, 13:52    [19718126]     Ответить | Цитировать Сообщить модератору
 Re: Вставить только уникальные значения  [new]
invm
Member

Откуда: Москва
Сообщений: 9646
virtuOS
Или причина в том, что данные вставляются в таблицу [dbo].[CallBack] и к ней же условие в not exists? Это же бред, по-моему.
Причина в том, что вставляете в параллельных сессиях. В этом случае нужно так:
		and not exists (
			select 1
			from [dbo].[CallBack] B with (updlock, serializable)
			where B.eventid = H.eventid
28 сен 16, 14:31    [19718401]     Ответить | Цитировать Сообщить модератору
 Re: Вставить только уникальные значения  [new]
aleks2
Guest
invm
virtuOS
Или причина в том, что данные вставляются в таблицу [dbo].[CallBack] и к ней же условие в not exists? Это же бред, по-моему.
Причина в том, что вставляете в параллельных сессиях. В этом случае нужно так:
		and not exists (
			select 1
			from [dbo].[CallBack] B with (updlock, serializable)
			where B.eventid = H.eventid


Нахрена?
Индекс с IGNORE_DUP_KEY = ON и фсе.

Сервер хоть вздохнет свободнее.
28 сен 16, 15:53    [19718990]     Ответить | Цитировать Сообщить модератору
 Re: Вставить только уникальные значения  [new]
invm
Member

Откуда: Москва
Сообщений: 9646
aleks2
Нахрена?
Индекс с IGNORE_DUP_KEY = ON и фсе.

Сервер хоть вздохнет свободнее.

А ignore_dup_key за счет святого духа работает?
+ О свободном дыхании
use tempdb;
go

create table dbo.t1 (id int);
create table dbo.t2 (id int primary key);
go

declare @c int = 1000000, @d int = 1000;

insert into dbo.t1
select top (@c)
 row_number() over (order by (select 1))
from
 master.dbo.spt_values a cross join
 master.dbo.spt_values b;

insert into dbo.t2
select top (@c / @d)
 id
from
 dbo.t1;

insert into dbo.t2
select top (@c)
 row_number() over (order by (select 1)) + @c
from
 master.dbo.spt_values a cross join
 master.dbo.spt_values b;

create unique index IX_t1 on dbo.t1(id);
create unique index IX_t2 on dbo.t2(id);
go

begin tran;

print '-------------- not exists(select ...) ------------------';
set statistics time on;
insert into dbo.t1
 select
  id
 from
  dbo.t2
 where
  not exists(select * from dbo.t1 with (updlock, serializable) where id = t2.id);
set statistics time off;
print '--------------------------------------------------------';

rollback;
go

create unique index IX_t1 on dbo.t1(id) with (drop_existing = on, ignore_dup_key = on);
go

begin tran;

print '--------------- ignore_dup_key = on --------------------';
set statistics time on;
insert into dbo.t1
 select
  id
 from
  dbo.t2
set statistics time off;
print '--------------------------------------------------------';

rollback;
go

drop table dbo.t1, dbo.t2;
go

-------------- not exists(select ...) ------------------

Время работы SQL Server:
Время ЦП = 7192 мс, затраченное время = 7491 мс.

(1000000 row(s) affected)
--------------------------------------------------------
--------------- ignore_dup_key = on --------------------

Время работы SQL Server:
Время ЦП = 7722 мс, затраченное время = 7956 мс.
Повторяющийся ключ пропущен.

(1000000 row(s) affected)
--------------------------------------------------------
28 сен 16, 16:26    [19719224]     Ответить | Цитировать Сообщить модератору
 Re: Вставить только уникальные значения  [new]
aleks2
Guest
invm
А ignore_dup_key за счет святого духа работает?


Опять тестирование "сферического святаго духа в вакууме"? Тест должен отражать реальность.

А в реальности - повторы ключа редкость.
Ты ж предлагаешь давить на тормоза каждый раз.

virtuOS
иногда (!) ругается на дублирование значений eventid при вставке в таблицу CallBack
29 сен 16, 06:53    [19721582]     Ответить | Цитировать Сообщить модератору
 Re: Вставить только уникальные значения  [new]
TaPaK
Member

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

Ставить игнор это закрыть глаза на некорректную обработку
29 сен 16, 07:33    [19721631]     Ответить | Цитировать Сообщить модератору
 Re: Вставить только уникальные значения  [new]
iap
Member

Откуда: Москва
Сообщений: 47052
TaPaK
aleks2,

Ставить игнор это закрыть глаза на некорректную обработку
Не совсем так. Каждый раз генерируется Warning.
29 сен 16, 10:57    [19722387]     Ответить | Цитировать Сообщить модератору
 Re: Вставить только уникальные значения  [new]
invm
Member

Откуда: Москва
Сообщений: 9646
aleks2
А в реальности - повторы ключа редкость.
Ты ж предлагаешь давить на тормоза каждый раз.
В реальности проверяется значение каждого ключа, вне зависимости от количества дубликатов.
29 сен 16, 11:03    [19722421]     Ответить | Цитировать Сообщить модератору
 Re: Вставить только уникальные значения  [new]
aleks2
Guest
invm
aleks2
А в реальности - повторы ключа редкость.
Ты ж предлагаешь давить на тормоза каждый раз.
В реальности проверяется значение каждого ключа, вне зависимости от количества дубликатов.

Ога. Тока serializable там не включается.
29 сен 16, 11:58    [19722818]     Ответить | Цитировать Сообщить модератору
 Re: Вставить только уникальные значения  [new]
invm
Member

Откуда: Москва
Сообщений: 9646
aleks2
Тока serializable там не включается.
Что, серьезно?
Пример тебе дан. Можешь расширить свои знания, поизучав какие там блокировки, когда и на что они выставляются.

Подсказка: поведение зависит от кластерности индекса.
29 сен 16, 12:40    [19723101]     Ответить | Цитировать Сообщить модератору
 Re: Вставить только уникальные значения  [new]
aleks2
Guest
invm
aleks2
Тока serializable там не включается.
Что, серьезно?
Пример тебе дан. Можешь расширить свои знания, поизучав какие там блокировки, когда и на что они выставляются.

Подсказка: поведение зависит от кластерности индекса.


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

ЗЫ. Если оно (значение ключа) и так и так проверяется - два раза проверять дольше чем один.
29 сен 16, 12:59    [19723265]     Ответить | Цитировать Сообщить модератору
 Re: Вставить только уникальные значения  [new]
invm
Member

Откуда: Москва
Сообщений: 9646
aleks2
Если оно (значение ключа) и так и так проверяется - два раза проверять дольше чем один.
Да. Особенно заметно в приведенном примере.
29 сен 16, 14:00    [19723647]     Ответить | Цитировать Сообщить модератору
 Re: Вставить только уникальные значения  [new]
Гавриленко Сергей Алексеевич
Member

Откуда: Moscow
Сообщений: 37155
Я вообще не понимаю, в чем экономия перфоманса с IGNORE_DUP_KEY.

Без него (но с проверкой надо):

1. Поискать запись
2. Если запись не нашлась, то вставить

С IGNORE_DUP_KEY надо:

1. Поискать, куда вставлять запись
2. Вставить

Т.е. с IGNORE_DUP_KEY вообще нет никакой экономии ничего (в отличие от первого варианта, позволяющего не производить вставку в случае дублирования ключа), только затраты на вставку и последуюшее вечное хранение (ну или там lazy-удалятель будет кушать ресурсы).

Сообщение было отредактировано: 29 сен 16, 14:24
29 сен 16, 14:23    [19723798]     Ответить | Цитировать Сообщить модератору
 Re: Вставить только уникальные значения  [new]
aleks2
Guest
Гавриленко Сергей Алексеевич
Т.е. с IGNORE_DUP_KEY вообще нет никакой экономии ничего (в отличие от первого варианта, позволяющего не производить вставку в случае дублирования ключа), только затраты на вставку и последуюшее вечное хранение (ну или там lazy-удалятель будет кушать ресурсы).


1. Экономия одной строки кода.
2. Экономия на хинтах, необходимых по мнению invm, для работы этой конструкции. IGNORE_DUP_KEY ваще плевать на все уровни изоляции.
29 сен 16, 14:37    [19723904]     Ответить | Цитировать Сообщить модератору
 Re: Вставить только уникальные значения  [new]
invm
Member

Откуда: Москва
Сообщений: 9646
Гавриленко Сергей Алексеевич
Я вообще не понимаю, в чем экономия перфоманса с IGNORE_DUP_KEY.
Экономия таки есть, если уникальный индекс - кластерный. Потому что все необходимые действия делаются в итераторе Clustered Index Insert.
А вот если некластерный, то строится план, практически аналогичный варианту с not exists().
aleks2
IGNORE_DUP_KEY ваще плевать на все уровни изоляции.
Ага. Новый уровень изоляции "IGNORE_DUP_KEY" - блокировок не ставит и игнорирует любые существующие.
Включается, только тогда, когда сервер распознает, что с ним работает aleks2 :)
29 сен 16, 14:59    [19724017]     Ответить | Цитировать Сообщить модератору
 Re: Вставить только уникальные значения  [new]
aleks2
Guest
invm
aleks2
IGNORE_DUP_KEY ваще плевать на все уровни изоляции.
Ага. Новый уровень изоляции "IGNORE_DUP_KEY" - блокировок не ставит и игнорирует любые существующие.
Включается, только тогда, когда сервер распознает, что с ним работает aleks2 :)

Ага или не ага.
Тока для работы многопоточной вставки с IGNORE_DUP_KEY хинта serializable не надо.
К чему бы это?
29 сен 16, 15:24    [19724174]     Ответить | Цитировать Сообщить модератору
 Re: Вставить только уникальные значения  [new]
invm
Member

Откуда: Москва
Сообщений: 9646
aleks2
Тока для работы многопоточной вставки с IGNORE_DUP_KEY хинта serializable не надо.
К чему бы это?
К тому что, serializable используется автоматом, если необходимо. Такая мысль не возникала?
Тебе уже предлагалось помониторить блокировки на готовом примере. Но ты же глупостями не занимаешься :)
29 сен 16, 15:29    [19724205]     Ответить | Цитировать Сообщить модератору
 Re: Вставить только уникальные значения  [new]
Гавриленко Сергей Алексеевич
Member

Откуда: Moscow
Сообщений: 37155
invm
Экономия таки есть, если уникальный индекс - кластерный. Потому что все необходимые действия делаются в итераторе Clustered Index Insert.
Я не очень понимаю, как это избавляет от необходимости физического поиска страницы, в которую надо вставить данные.

Сообщение было отредактировано: 29 сен 16, 15:52
29 сен 16, 15:52    [19724382]     Ответить | Цитировать Сообщить модератору
 Re: Вставить только уникальные значения  [new]
aleks2
Guest
invm
aleks2
Тока для работы многопоточной вставки с IGNORE_DUP_KEY хинта serializable не надо.
К чему бы это?
К тому что, serializable используется автоматом, если необходимо. Такая мысль не возникала?
Тебе уже предлагалось помониторить блокировки на готовом примере. Но ты же глупостями не занимаешься :)


Но хинта то не надо. А ужо что там выбирается "автоматом"...
29 сен 16, 16:00    [19724433]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить