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

В теме https://www.sql.ru/forum/1325377/optimizirovat-vremya-vypolneniya-zaprosa возникла дискуссия на тему стоил ли использовать колумнстор для выборки небольшого числа данных, а не агрегатов.

На MSDN есть статья где имеются рекомендации об оптимизации под колумнстор.

https://docs.microsoft.com/en-us/sql/relational-databases/indexes/columnstore-indexes-query-performance?view=sql-server-ver15 Рекомендую всем ознакомиться.

Также скажу, что знаю случаи успешного использования колумнстора в OLTP системах, а не только аналитических (dwh). При этом я не призываю совать колумнстор всюду, куда только можно.

Предлагаю вашему внимаю тестовое репо, которое призвано сравнить плоскую таблицу со многим индексами (типа на все случаи) и партиционированный колумстор. Сравнивается выборка небольшого числи строки и не всех полей.

Сравнение исходит их таких предположений.
1) Таблица достаточно большая. (в тесте 10 млн).
2) В запросах присутствует фильтрация по полю партициониррования
3) Выборка или обновление затрагивает небольшой объем данных (десятки строк) более свойственный OLTP чем DWH

Мой вывод такой: при значительно меньше занимаемом месте, партиционированный колумстор не уступает по производительности обычной таблице с индексами с указанными выше допущениями.


Код: 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.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
215.
216.
217.
218.
219.
220.
221.
222.
223.
224.
225.
226.
227.
228.
229.
230.
231.
232.
233.
234.
235.
236.
237.
238.
239.
240.
241.
242.
243.
244.
245.
246.
247.
248.
249.
250.
251.
252.
253.
254.
255.
256.
257.
258.
259.
260.
261.
262.
263.
264.
265.
266.
267.
268.
269.
270.
271.
272.
273.
274.
275.
276.
277.
278.
279.
280.
281.
282.
283.
284.
285.
286.
287.
288.
289.
290.
291.
292.
293.
294.
295.
296.
297.
298.
299.
300.
301.
302.
303.
304.
305.
306.
307.
308.
309.
310.
311.
312.
313.
314.
315.
316.
317.
318.
319.
320.
321.
322.
323.
324.
325.
326.
327.
328.
329.
330.
331.
332.
333.
334.
335.
336.
337.
338.
339.
340.
341.
342.
343.
344.
345.
346.
347.
348.
349.
350.
351.
352.
353.
354.
355.
356.
357.
358.
359.
360.
361.
362.
363.
364.
365.
366.
367.
368.
369.
370.
371.
372.
373.
374.
375.
376.
377.
378.
379.
380.
381.
382.
383.
use tempdb 
GO 

SET NOCOUNT ON 
GO 

CREATE SEQUENCE seq1  START WITH 0  INCREMENT BY 1 ;  

create table t (
	a0 int not null PRIMARY KEY CLUSTERED,
	a1 int not null, 
	a2 int not null, 
	a3 int not null, 
	a4 int not null,
	a5 int not null,
	a6 int not null,
	a7 int not null,
	a8 int not null,
	a9 int not null
	);
GO

INSERT INTO t SELECT 
	NEXT VALUE FOR seq1, 
	NEXT VALUE FOR seq1 % 13, 
	NEXT VALUE FOR seq1 % 17,
	NEXT VALUE FOR seq1 % 5,
	NEXT VALUE FOR seq1 % 101,
	NEXT VALUE FOR seq1 % 107,
	NEXT VALUE FOR seq1 % 1291,
	NEXT VALUE FOR seq1 % 1000000,
	NEXT VALUE FOR seq1 % 17471,
	NEXT VALUE FOR seq1 % 86453
GO 100

INSERT INTO t 
SELECT 
	NEXT VALUE FOR seq1, 
	NEXT VALUE FOR seq1 % 13, 
	NEXT VALUE FOR seq1 % 17,
	NEXT VALUE FOR seq1 % 5,
	NEXT VALUE FOR seq1 % 101,
	NEXT VALUE FOR seq1 % 107,
	NEXT VALUE FOR seq1 % 1291,
	NEXT VALUE FOR seq1 % 1000000,
	NEXT VALUE FOR seq1 % 17471,
	NEXT VALUE FOR seq1 % 86453
FROM (SELECT TOP 99 * FROM t) t
GO 100

SET NOCOUNT OFF
GO 


INSERT INTO t 
SELECT 
	NEXT VALUE FOR seq1, 
	NEXT VALUE FOR seq1 % 13, 
	NEXT VALUE FOR seq1 % 17,
	NEXT VALUE FOR seq1 % 5,
	NEXT VALUE FOR seq1 % 101,
	NEXT VALUE FOR seq1 % 107,
	NEXT VALUE FOR seq1 % 1291,
	NEXT VALUE FOR seq1 % 1000000,
	NEXT VALUE FOR seq1 % 17471,
	NEXT VALUE FOR seq1 % 86453
FROM (SELECT TOP 9900 * FROM t) t
GO 100

INSERT INTO t 
SELECT 
	NEXT VALUE FOR seq1, 
	NEXT VALUE FOR seq1 % 13, 
	NEXT VALUE FOR seq1 % 17,
	NEXT VALUE FOR seq1 % 29,
	NEXT VALUE FOR seq1 % 101,
	NEXT VALUE FOR seq1 % 107,
	NEXT VALUE FOR seq1 % 1291,
	NEXT VALUE FOR seq1 % 1000000,
	NEXT VALUE FOR seq1 % 17471,
	NEXT VALUE FOR seq1 % 86453
FROM (SELECT TOP 900000 * FROM t) t
GO 10


--SELECT CONCAT(10000 * ROW_NUMBER() OVER (ORDER BY 1/0), ',') FROM t;
--GO
--SELECT '[PRIMARY],' FROM t;
--GO

CREATE PARTITION FUNCTION range100 (int)  
AS RANGE LEFT FOR VALUES (
10000,
20000,
30000,
40000,
50000,
60000,
70000,
80000,
90000,
100000,
110000,
120000,
130000,
140000,
150000,
160000,
170000,
180000,
190000,
200000,
210000,
220000,
230000,
240000,
250000,
260000,
270000,
280000,
290000,
300000,
310000,
320000,
330000,
340000,
350000,
360000,
370000,
380000,
390000,
400000,
410000,
420000,
430000,
440000,
450000,
460000,
470000,
480000,
490000,
500000,
510000,
520000,
530000,
540000,
550000,
560000,
570000,
580000,
590000,
600000,
610000,
620000,
630000,
640000,
650000,
660000,
670000,
680000,
690000,
700000,
710000,
720000,
730000,
740000,
750000,
760000,
770000,
780000,
790000,
800000,
810000,
820000,
830000,
840000,
850000,
860000,
870000,
880000,
890000,
900000,
910000,
920000,
930000,
940000,
950000,
960000,
970000,
980000,
990000,
1000000);  
GO  
CREATE PARTITION SCHEME RANGE100ps  
AS PARTITION RANGE100  
TO ( 
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY],
[PRIMARY]); 


create table t_CS (
	a0 int not null,
	a1 int not null, 
	a2 int not null, 
	a3 int not null, 
	a4 int not null,
	a5 int not null,
	a6 int not null,
	a7 int not null,
	a8 int not null,
	a9 int not null
	) ON RANGE100ps(a7);
go 

INSERT INTO t_CS
SELECT * FROM t 
GO 

CREATE CLUSTERED COLUMNSTORE INDEX IX_T_CS ON t_CS ON RANGE100ps(a7);
GO 

CREATE INDEX IX_T_a7a3 ON t(a7, a3) INCLUDE (a4)
GO 
CREATE INDEX IX_T_a3456 ON t(a3,a4,a5,a6)
GO 
CREATE INDEX IX_T_a469 ON t(a4,a6,a9)
GO 
CREATE INDEX IX_T_a829 ON t(a8,a2,a9) INCLUDE (a3, a4)
GO 
CREATE INDEX IX_T_a137 ON t(a1,a3,a7) INCLUDE (a2, a4)
GO 

SELECT @@VERSION 
GO
-- распределение по партициям 
SELECT COUNT(*), a7 / 10000 FROM t_CS
GROUP BY a7 / 10000
ORDER BY a7 / 10000
GO 

DBCC FREEPROCCACHE 
GO 

SET STATISTICS TIME ON;  
SELECT a7, a3, a4 FROM t WHERE a7 = 33 --AND a3 = 2
SET STATISTICS TIME OFF; 
GO 

DBCC FREEPROCCACHE 
GO 
SET STATISTICS TIME ON;  
SELECT a7, a3, a4 FROM t_CS WHERE a7 = 33 --AND a3 = 2
SET STATISTICS TIME OFF; 
GO 

DBCC FREEPROCCACHE 
GO 
SET STATISTICS TIME ON;  
UPDATE t SET a3 = a7 WHERE a7 = 33
SET STATISTICS TIME OFF; 
GO 

DBCC FREEPROCCACHE 
GO 
SET STATISTICS TIME ON;  
UPDATE t_CS  SET a3 = a7 WHERE a7 = 33
SET STATISTICS TIME OFF; 
GO 

EXEC sp_spaceused 't';
GO 
EXEC sp_spaceused 't_CS';
GO 

DROP SEQUENCE seq1;
GO
DROP TABLE t;
GO
DROP TABLE t_CS;
GO
DROP PARTITION SCHEME RANGE100ps; 
GO
DROP PARTITION FUNCTION RANGE100;
GO

...
Рейтинг: 0 / 0
Таблица с индексами vs партиционированный колумнстор
    #39959103
Фотография a_voronin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Microsoft SQL Server 2019 (RTM-GDR) (KB4517790) - 15.0.2070.41 (X64) Oct 28 2019 19:56:59 Copyright (C) 2019 Microsoft Corporation Developer Edition (64-bit) on Windows Server 2016 Standard 10.0 <X64> (Build 14393: )
...
Рейтинг: 0 / 0
Таблица с индексами vs партиционированный колумнстор
    #39959148
felix_ff
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a_voronin,

вы понимаете что выигрыш в скорости не обеспечивается напрямую индексом columnstorе в Вашем тесте? там играет роль в основном partition elimination.

вы с тем же успехом могли создать партиционированную таблицу кучу и она тоже бы показала по скорости обработки вполне неплохие результаты
...
Рейтинг: 0 / 0
Таблица с индексами vs партиционированный колумнстор
    #39959159
Фотография alexeyvg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a_voronin
Предлагаю вашему внимаю тестовое репо, которое призвано сравнить плоскую таблицу со многим индексами (типа на все случаи) и партиционированный колумстор. Сравнивается выборка небольшого числи строки и не всех полей.

Сравнение исходит их таких предположений.
1) Таблица достаточно большая. (в тесте 10 млн).
2) В запросах присутствует фильтрация по полю партициониррования
3) Выборка или обновление затрагивает небольшой объем данных (десятки строк) более свойственный OLTP чем DWH

Мой вывод такой: при значительно меньше занимаемом месте, партиционированный колумстор не уступает по производительности обычной таблице с индексами с указанными выше допущениями.
Спасибо за скрипт репро, будет что покрутить на досуге :-)

Сразу бросается в глаза, что плоская таблицу со многим индексами (типа на все случаи), а запрос к колумнстору только в расчёте на одно поле секционирования.
Тогда уж нужно сравнить по объёму такие же варианты секционирования, как и индексируемые поля в индексах.
Ой, это же невозможно, колумнстор индекс может быть только олдин, как же тогда быть с запросами, для которых построены индексы в примере?
Например:
Код: sql
1.
SELECT a7, a3, a4 FROM t WHERE a8 = 33 AND a2 = 2


Ага, прочитало 13300 страниц, в 100 сегментах.
А обычный индекс? 3 страницы. (да, не одну, потому что заголовок + следующий уровень, целых три получилось)

Хорошо, пусть даже запросы только по условию с полем a7.
Смотрим, и что?
Обычный индекс - 3 страницы, колумнстор - 125 страниц.

Не смотрю пока, что там с размерами (потому что прямо сравнивать индексы на все случаи с индексом на один случай некорректно), но по скорости проигрыш во много раз.
...
Рейтинг: 0 / 0
Таблица с индексами vs партиционированный колумнстор
    #39959161
Фотография alexeyvg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
felix_ff
вы с тем же успехом могли создать партиционированную таблицу кучу и она тоже бы показала по скорости обработки вполне неплохие результаты
Или ещё лучше кластерный индекс по a7
...
Рейтинг: 0 / 0
Таблица с индексами vs партиционированный колумнстор
    #39959276
msLex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a_voronin,

Если бы вы глянули на IO статистику, вы бы все поняли сами.



Даже на вашем тесте, который очень очень перекошен в сторону "CS не так уж и плох" (я ниже пробегусь по ключевым моментам) результаты вполне однозначны


Выборка из обычной таблицы

Код: plaintext
1.
2.
(10 rows affected)
Table 't'. Scan count 1, logical reads 3, physical reads 2, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Итого 5 IO

Выборка из CS

Код: plaintext
1.
2.
3.
(10 rows affected)
Table 't_CS'. Scan count 1, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 125, lob physical reads 2, lob read-ahead reads 215.
Table 't_CS'. Segment reads 1, segment skipped 0.
Итого 332 IO


UPDATE обычной таблицы

Код: plaintext
1.
2.
Table 't'. Scan count 1, logical reads 297, physical reads 102, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Worktable'. Scan count 1, logical reads 23, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Итого 422 IO

UPDATE CS
Код: plaintext
1.
2.
3.
Table 't_CS'. Scan count 2, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 671, lob physical reads 8, lob read-ahead reads 900.
Table 't_CS'. Segment reads 2, segment skipped 0.
Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Итого 1579 IO


Ну и немного на закуску


Выборка из обычной таблицы после UPDATE

Код: plaintext
1.
2.
(10 rows affected)
Table 't'. Scan count 1, logical reads 3, physical reads 2, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

Ничего не изменилось, те же 5 IO

Выборка из CS после UPDATE
Код: plaintext
1.
2.
3.
(10 rows affected)
Table 't_CS'. Scan count 2, logical reads 3, physical reads 1, read-ahead reads 0, lob logical reads 125, lob physical reads 2, lob read-ahead reads 215.
Table 't_CS'. Segment reads 1, segment skipped 0.
Как видим, помимо обычных 332 IO, добавились еще 4 (те самые дельтастор).




В общем ЧТД

выборка по ключу из CS хуже чем из индекса на 2 порядка
обновление CS хуже обновления таблицы с обычными индексами в 3 раза


Теперь обещанный разбор теста


1. Как уже говорили до меня, ваш CS заточен строго под 1 запрос, прочие запросы показывают гораздо (еще на порядок) худшие результаты

2. Индексы на обычной таблице не лучшие для этого конкретного запроса (напомню, что CS вы оптимизировали именно под 1 запрос).

3. Размер секций 100к записей.
В исходной теме упоминалась цифра миллиард записей.
С секциями такого размера это 10000 партиций, что практически предел (максимум их может быть 15000), т.е. при таком размере секций у вас просто нет места под второй миллиард записей.
Увеличение размера секций приведет к практически линейному росту IO как при чтении так и при обновлении.

4. Как уже говорили, основной выигрыш в чтении по ключу секционирования именно из-за partition elimination.
...
Рейтинг: 0 / 0
Таблица с индексами vs партиционированный колумнстор
    #39959374
Фотография alexeyvg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
msLex
1. Как уже говорили до меня, ваш CS заточен строго под 1 запрос, прочие запросы показывают гораздо (еще на порядок) худшие результаты
На поряд ки . Запрос, оптимальный для выбранной колонки секционирования, в 50-100 раз медленнее.
А другие в 1000 - 10 000.
...
Рейтинг: 0 / 0
Таблица с индексами vs партиционированный колумнстор
    #39959390
msLex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alexeyvg
msLex
1. Как уже говорили до меня, ваш CS заточен строго под 1 запрос, прочие запросы показывают гораздо (еще на порядок) худшие результаты
На поряд ки . Запрос, оптимальный для выбранной колонки секционирования, в 50-100 раз медленнее.
А другие в 1000 - 10 000.

ну я говорю "еще на 1 прядок", т.е. хуже не на 2 (100) а на 3(1000) порядка.
...
Рейтинг: 0 / 0
Таблица с индексами vs партиционированный колумнстор
    #39959391
Фотография a_voronin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alexeyvg
msLex
1. Как уже говорили до меня, ваш CS заточен строго под 1 запрос, прочие запросы показывают гораздо (еще на порядок) худшие результаты
На поряд ки . Запрос, оптимальный для выбранной колонки секционирования, в 50-100 раз медленнее.
А другие в 1000 - 10 000.


Ну а как измениться расклад, если колонок будет 50, или они будут тяжелые (строковые), а выбирать будем несколько легких полей?

Что касается размера партиций -- пусть будет 1000 партиций на 1 млд. Понятно, что 10000 партиций городить уже другой рода оверхед возникнуть может.
...
Рейтинг: 0 / 0
Таблица с индексами vs партиционированный колумнстор
    #39959408
msLex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a_voronin
Ну а как измениться расклад, если колонок будет 50, или они будут тяжелые (строковые), а выбирать будем несколько легких полей?


1. Так у нас (вас) в тесте покрывающие индексы, в них не будет ненужных тяжелых строковых полей.
2. Обычно в OLTP строковые поля хранятся в справочниках. Нормализация, как ни как.
3. Мы же обсуждаем конкретную ситуацию, а не пытаемся придумать ту, в которой CS будет лучше.
Ситуации где CS будет лучше безусловно есть.


a_voronin
Что касается размера партиций -- пусть будет 1000 партиций на 1 млд. Понятно, что 10000 партиций городить уже другой рода оверхед возникнуть может.

Это ухудшит результаты CS еще на 1 порядок.


Вот такие цифры на выборку при увеличении секции в 10 раз
Код: plaintext
1.
2.
3.
(10 rows affected)
Table 't_CS'. Scan count 1, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 933, lob physical reads 2, lob read-ahead reads 2968.
Table 't_CS'. Segment reads 1, segment skipped 0.
Итого 3903 IO
...
Рейтинг: 0 / 0
Таблица с индексами vs партиционированный колумнстор
    #39959417
Фотография alexeyvg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
msLex
alexeyvg
На поряд ки . Запрос, оптимальный для выбранной колонки секционирования, в 50-100 раз медленнее.
А другие в 1000 - 10 000.

ну я говорю "еще на 1 прядок", т.е. хуже не на 2 (100) а на 3(1000) порядка.
А, понял, невнимательно прочитал...

a_voronin
Ну а как измениться расклад, если колонок будет 50, или они будут тяжелые (строковые), а выбирать будем несколько легких полей?
Мы сравнивали с индексом, который включает в include секции все необходимые для выборки поля.
Конечно, в реальной системе возможны много вариантов.

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

2. Обычно в OLTP строковые поля хранятся в справочниках. Нормализация, как ни как.


Вот с этим я сильно не соглашусь. Это в DWH они хранятся в справочниках. А в OLTP такое в строках сидит.

К тому же я имею дело сейчас с SAP данными. Они ключи любят NVARCHAR(10) NVARCHAR(20) городить. И у ТС в той теме тоже самое, если посмотрите внимательно.

Это в DWH текстовые поля убирают в справочники. А тут заказы, поставки, Юзера, все набито текстовыми полями. Какой-нибудь коммент типа nvarchar(2000) частенько присутствует. Ну а username, ФИО, адрес, все сидит в строках.
...
Рейтинг: 0 / 0
Таблица с индексами vs партиционированный колумнстор
    #39959428
Фотография alexeyvg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a_voronin
На MSDN есть статья где имеются рекомендации об оптимизации под колумнстор.

https://docs.microsoft.com/en-us/sql/relational-databases/indexes/columnstore-indexes-query-performance?view=sql-server-ver15 Рекомендую всем ознакомиться.
И там в самом начале, а так же ещё несколько раз в тексте написано, что колумнстор индексы предназначены для аналитических запросов.

В общем описании колумнстор индексов https://docs.microsoft.com/ru-ru/sql/relational-databases/indexes/columnstore-indexes-overview?view=sql-server-ver15
есть раздел "Когда следует использовать индекс columnstore?"
Там написано:
BOLКак сделать выбор между индексами rowstore и columnstore?

Индексы rowstore лучше всего работают с запросами, направленными на поиск данных или определенного значения, а также с запросами в небольших диапазонах данных. Используйте индексы rowstore с транзакционными рабочими нагрузками, так как для них чаще требуется поиск по таблицам, а не сканирование таблиц.

Индексы columnstore обеспечивают значительное повышение производительности при выполнении аналитических запросов, которые сканируют большие объемы данных (в частности, большие таблицы). Используйте индексы columnstore с рабочими нагрузками по хранению и аналитике данных (в частности, с таблицами фактов), так как для них чаще требуется полное сканирование таблиц, а не поиск по таблицам.Притом можно даже сделать такой индекс на обычной таблице, с обычными индексами.

Тогда обсуждаемый запрос будет выполняться максимально эффективно с обычным индексом, а аналитические запросы - с колумнсторным.
...
Рейтинг: 0 / 0
Таблица с индексами vs партиционированный колумнстор
    #39959440
msLex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a_voronin
К тому же я имею дело сейчас с SAP данными. Они ключи любят NVARCHAR(10) NVARCHAR(20) городить. И у ТС в той теме тоже самое, если посмотрите внимательно.


NVARCHAR(20) - это не огромные строки, это всего 40 байт



a_voronin
Это в DWH текстовые поля убирают в справочники.

в CS, кстати, это не обязательно, т.к. справочники создаются автоматически "внутри CS", причем не на сегмент а на всю секцию

a_voronin

А тут заказы, поставки, Юзера, все набито текстовыми полями. Какой-нибудь коммент типа nvarchar(2000) частенько присутствует. Ну а username, ФИО, адрес, все сидит в строках.


Это вы не правильные OLTP смотрите.
В правильных (АКА нормализованных) OLTP системах, адрес строкой в строке заказа быть не может.

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

a_voronin
Это в DWH текстовые поля убирают в справочники.

в CS, кстати, это не обязательно, т.к. справочники создаются автоматически "внутри CS", причем не на сегмент а на всю секцию

a_voronin

А тут заказы, поставки, Юзера, все набито текстовыми полями. Какой-нибудь коммент типа nvarchar(2000) частенько присутствует. Ну а username, ФИО, адрес, все сидит в строках.


Это вы не правильные OLTP смотрите.
В правильных (АКА нормализованных) OLTP системах, адрес строкой в строке заказа быть не может.



Одна колонка это не справочник. Справочник это часто таблица с 10 и более колонками. Тот же адрес ещё имеет, регион, город, ближайший склад и т.п.

Я смотрю реальные OLTP в компаниях занимающих лидирующие позиции на рынке в своих отраслях. Упоминаемые в списках Forbes и т.п. Код там не написан согласно канонам оптимизации, и, честно говоря, я ни разу не видел ни одного OLTP, где все было бы оптимизировано. Более того, есть ситуации, когда готовые работающие говно решения многократно множатся. И это источники данных с которыми приходится работать. Особенно это применимо к SAP и 1C.
...
Рейтинг: 0 / 0
Таблица с индексами vs партиционированный колумнстор
    #39959485
msLex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Модератор: Исходный пример обсужден.
Количественный ответ получен.
Тема закрыта
...
Рейтинг: 0 / 0
16 сообщений из 16, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Таблица с индексами vs партиционированный колумнстор
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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