powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Два подхода к обновлению данных
5 сообщений из 5, страница 1 из 1
Два подхода к обновлению данных
    #39933350
Фотография a_voronin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Господа, часто возникает необходимость обновлять в таблице некий диапазон данных. Простейшее решение, к которому многие прибегают -- это "все удалить -- все вставить".

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
CREATE TABLE X(ID INT IDENTITY(1,1), DT DATETIME, VAL NVARCHAR(10), AMOUNT DECIMAL(18,4))

INSERT INTO X(DT, VAL, AMOUNT) VALUES('2020-01-01', N'Коровы', 10.5)
INSERT INTO X(DT, VAL, AMOUNT) VALUES('2020-01-02', N'Куры', 150.2)
INSERT INTO X(DT, VAL, AMOUNT) VALUES('2020-01-03', N'Свиньи', 70.1)
INSERT INTO X(DT, VAL, AMOUNT) VALUES('2020-01-04', N'Голуби', 7)

DELETE FROM X WHERE DT >= '2020-01-02'

INSERT INTO X(DT, VAL, AMOUNT) VALUES('2020-01-02', N'Куры', 150.2)
INSERT INTO X(DT, VAL, AMOUNT) VALUES('2020-01-03', N'Свиньи', 76.1)
INSERT INTO X(DT, VAL, AMOUNT) VALUES('2020-01-03', N'Овцы', 66.7)

SELECT * FROM X
GO 
DROP TABLE X
GO 



Но существует другой подход -- провести подробное сравнение и обновить только то, что нужно.

Код: 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.
CREATE TABLE X(ID INT IDENTITY(1,1), DT DATETIME, VAL NVARCHAR(10), AMOUNT DECIMAL(18,4))
GO
INSERT INTO X(DT, VAL, AMOUNT) VALUES('2020-01-01', N'Коровы', 10.5)
INSERT INTO X(DT, VAL, AMOUNT) VALUES('2020-01-02', N'Куры', 150.2)
INSERT INTO X(DT, VAL, AMOUNT) VALUES('2020-01-03', N'Свиньи', 70.1)
INSERT INTO X(DT, VAL, AMOUNT) VALUES('2020-01-04', N'Голуби', 7)

MERGE X AS Target
USING (
	SELECT * FROM (
		VALUES(	'2020-01-02', N'Куры', 150.2),
				('2020-01-03', N'Свиньи', 76.1),
				('2020-01-03', N'Овцы', 66.7)
	) Source(DT, VAL, AMOUNT) 
) AS Source ON Source.DT = Target.DT AND Source.VAL = Target.VAL
WHEN MATCHED AND Target.DT >= '2020-01-02' AND Target.AMOUNT <> Source.AMOUNT THEN 
    UPDATE SET Target.AMOUNT = Source.AMOUNT
WHEN NOT MATCHED BY SOURCE AND Target.DT >= '2020-01-02' THEN 
    DELETE 
WHEN NOT MATCHED BY TARGET THEN 
    INSERT (DT, VAL, AMOUNT) VALUES(DT, VAL, AMOUNT)
;

SELECT * FROM X

GO 
DROP TABLE X



Второй подход естественно требует более громоздкого кода.

Вопрос: при каких обстоятельствах с точки зрения производительности стоит прибегать к первому, а в каких ко второму подходу? И как определить грань, где какой будет оптимален?
...
Рейтинг: 0 / 0
Два подхода к обновлению данных
    #39933354
L_argo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
При больших объемах, но небольших приращениях "вставить все" это очень неоптимально.
Грань определяется только импирически.
...
Рейтинг: 0 / 0
Два подхода к обновлению данных
    #39933410
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a_voronin,

если вам нужна высокая доступность, то делайте через переключение секций. Таблицу на замещение секции можно заполнить вставкой, если это быстрее.
...
Рейтинг: 0 / 0
Два подхода к обновлению данных
    #39933416
Фотография a_voronin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Владислав Колосов,

Речь идет о тонком обновлении, которое может включать применительно к конкретным записям INSERT UPDATE DELETE NOCHANGE. Соответственно никакое переключение секций тут не поможет. Разве что делать обновление в соседней таблице и потом перегонят и инкремент.
...
Рейтинг: 0 / 0
Два подхода к обновлению данных
    #39933559
Ferdipux
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
a_voronin,

IMHO, Если таблица Х - обычная, то при наличии необходимых индексов (см. Optimizing MERGE Statement Performance ) и прочих условий MERGE может быть быстрее. А может и не быть - в вашем "простом" примере удаление идет с фильтром по DT, если по нему есть индекс - DELETE + INSERT может быть быстрее, не требуется сличать записи по ключу DT+VAL.

Если таблица типа columnstore, то DELETE + INSERT однозначно выигрывает у MERGE.
...
Рейтинг: 0 / 0
5 сообщений из 5, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Два подхода к обновлению данных
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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