powered by simpleCommunicator - 2.0.52     © 2025 Programmizd 02
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Как биективно отобразить множество на ряд целых чисел, как можно компактнее?
15 сообщений из 40, страница 2 из 2
Как биективно отобразить множество на ряд целых чисел, как можно компактнее?
    #40048872
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
uaggster,

чтобы секционирование как-то помогало, в запросе должен участвовать ключ секционирования.
...
Рейтинг: 0 / 0
Как биективно отобразить множество на ряд целых чисел, как можно компактнее?
    #40049051
uaggster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Владислав Колосов
uaggster,

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

Так он и участвует!
Это тот самый [key]. По нему секционирование и сделано.
И partition elimination тоже выполняется.
Проблема в том, что когда я указываю в запросе [key] = 6001012 (например), сервер оценивает количество записей не равному количеству в секции, а на основе статистике по этому полю, а она - дырявая, см. выше, и частенько полагает количество значений = 1,
Не смотря на то, что секция - полная, и в ней миллионы записей.

OPTIMIZE FOR - хорошая идея, попробую ее.

Кроме того, попробую посмотреть, как будет считаться статистика по такому ключу:
Cast(k as binary(1)) + Cast((n * 16) | Cast(m as binary(1)) as binary(1)) key_bin
Или
Cast(Cast(k as binary(1)) + Cast((n * 16) | Cast(m as binary(1)) as binary(1)) as smallint) key_int

Интересно, что получится.
...
Рейтинг: 0 / 0
Как биективно отобразить множество на ряд целых чисел, как можно компактнее?
    #40049116
uaggster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Создал таблицу, на той же самой партишн схема, что и оригинальная таблица, но из 4х столбцов: кластерного индекса (ид строки + ключ партиционирования, старый), ключ small int, ключ binary(2).
Создал статистики по полям.
Удивительно, но получил разные характеристики статистики ключей в виде smallint и binary(2).
Причем существенно разные.
Не смотря на то, что это одни и те же данные в байтовом виде.
Почему так, интересно???
Причем, обратите внимание, в таблице 1437 уникальных значений ключа.
Почему для бинарного ключа другая плотность?
Я специально перепроверил - и там, и там значения, в смысле байтов - одинаковые.
...
Рейтинг: 0 / 0
Как биективно отобразить множество на ряд целых чисел, как можно компактнее?
    #40050515
Gerros
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А вам обязательно хранить все строки в одной таблице?

Для ваших данных формулу непрерывной функции уже озвучивали, x = k*7*12 + n*12 + m.
Максимальное значение будет 60*7*12 + 6*12 + 11 = 5123.
В гистограмме 200 шагов, значит нужно сделать 5124/200 + 1 = 26 таблиц. Назовём их s00...s25.
В таблице s00 храним строки для которых 0 <= x <= 199.
В таблице s01 храним строки для которых 200 <= x <= 399.
И так далее.
В каждой таблице делаем поле sx = x % 200, оно всегда в диапазоне [0...199], помещается в tinyint, по нему наверное индекс можно будет построить с детальной гистограммой как вам надо.

Допустим, вам нужно найти строки с набором (k,n,m) = (49,5,1):
x = k*7*12+n*12+m = 4177
s = x / 200 = 20
sx = x % 200 = 177
Здесь s - это номер таблицы.
Соответствуюий запрос будет:
Код: sql
1.
select * from s20 where sx = 177


Придётся написать специальное приложение которое сможет вычислять имя таблицы, ну или написать динамический sql.

Второй вариант - сделать одну таблицу, но в ней сделать 26 колонок sx00...sx25 и одну колонку s - по ней сделать секционирование.
В "нулевой" секции в колонке sx00 будут значения sx = x % 200, в остальных колонках - null.
В "первой" секции в колонке sx01 будут значения sx = x % 200, в остальных колонках - null. И так далее.
По каждой из этих колонок делаем индекс. Наверное можно будет сделать инкрементный.
Но всё равно будет динамика или специальное приложение:
Код: sql
1.
select * from t where s = 20 and s20 = 177



Функции:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
select
  k = k3*10*10 + k2*10 + k1, n, m,
  x = convert( smallint, (k3*10*10 + k2*10 + k1)*7*12 + n*12 + m),
  s = ((k3*10*10 + k2*10 + k1)*7*12 + n*12 + m) / 200,
  sx= ((k3*10*10 + k2*10 + k1)*7*12 + n*12 + m) % 200
from( values (0),(1),(2),(3),(4),(5),(6)) n(n) --7
cross
join( values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11)) m(m) --12
cross
join( values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) k1(k1) --10
cross
join( values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) k2(k2) --10
cross
join( values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9),(10)) k3(k3)
where (k3*10*10 + k2*10 + k1)*7*12 + n*12 + m <= 32767
  and k3*10*10 + k2*10 + k1 <= 60
order by k, n, m
...
Рейтинг: 0 / 0
Как биективно отобразить множество на ряд целых чисел, как можно компактнее?
    #40050528
uaggster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Gerros, т.е. не только порезать данные на 5000 секций, но и на ~ 10 таблиц?
Теоретически - возможно, но боюсь оптимизатор с ума сойдет, строя планы по view из секционированных таблиц.
Фишка в том, что выборки считаются по всему набору данных, которые нужно пополнять большими кусками.
...
Рейтинг: 0 / 0
Как биективно отобразить множество на ряд целых чисел, как можно компактнее?
    #40050559
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
uaggster,

smallint имеет знак, может поэтому? Длина ключа разная, кроме того.
...
Рейтинг: 0 / 0
Как биективно отобразить множество на ряд целых чисел, как можно компактнее?
    #40050657
Gerros
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
uaggster
Gerros, т.е. не только порезать данные на 5000 секций, но и на ~ 10 таблиц?
Теоретически - возможно, но боюсь оптимизатор с ума сойдет, строя планы по view из секционированных таблиц.
Фишка в том, что выборки считаются по всему набору данных, которые нужно пополнять большими кусками.

Либо несколько таблиц, либо несколько полей в одной (возможно секционированной) таблице.
У Вас всего 5124 комбинации ключей. Чтобы гистограмма была точной, нужно чтобы поле содержало не более 200 различных значений.

Если сделать 26 таблиц, то в каждой таблице будет не более 200 комбинаций, а значит, гистограмма будет точная. Это первый вариант.
Вьюха по таблицам сделает невозможным использование индекса.

Второй вариант - таблица одна, но в ней 26 полей. Опять-таки гистограмма будет точная. При этом саму таблицу можно секционировать.
...
Рейтинг: 0 / 0
Как биективно отобразить множество на ряд целых чисел, как можно компактнее?
    #40050700
uaggster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Владислав Колосов
uaggster,

smallint имеет знак, может поэтому? Длина ключа разная, кроме того.

Три раза перепроверил - это одно и то же значение, если рассматривать бинарное представление. Т.е. я ничего не напутал. Одно и то же число в бинарном виде и в виде smallint в поле дает разную плотность и, гистограмму разную.
Причем, обратите внимание, в таблице 1437 уникальных значений ключа.
Плотность должна быть 1/1437 ~ 0.00006
Какого черта она для бинарного представления в два раза больше???
...
Рейтинг: 0 / 0
Как биективно отобразить множество на ряд целых чисел, как можно компактнее?
    #40050706
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
uaggster,

нет, плотность рассчитана верно - 6.95E-4

А бинарная плотность ровно вдвое выше.
...
Рейтинг: 0 / 0
Как биективно отобразить множество на ряд целых чисел, как можно компактнее?
    #40050709
uaggster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Gerros
uaggster
Gerros, т.е. не только порезать данные на 5000 секций, но и на ~ 10 таблиц?
Теоретически - возможно, но боюсь оптимизатор с ума сойдет, строя планы по view из секционированных таблиц.
Фишка в том, что выборки считаются по всему набору данных, которые нужно пополнять большими кусками.

Либо несколько таблиц, либо несколько полей в одной (возможно секционированной) таблице.
У Вас всего 5124 комбинации ключей. Чтобы гистограмма была точной, нужно чтобы поле содержало не более 200 различных значений.

Если сделать 26 таблиц, то в каждой таблице будет не более 200 комбинаций, а значит, гистограмма будет точная. Это первый вариант.

Ну, в моем варианте, скорее 60 таблиц, но не суть.
Это было опробовано.
Секционированное представление оказалось даже более "тормознутым", чем секционированная таблица.
Плюс ко всему, если запрос затрагивает несколько секций представления - сервер ошибается (в нашем случае) - еще фатальнее.
Хотя, в принципе, мы не исследовали вариант глубоко - может и прокатить.

Вьюха по таблицам сделает невозможным использование индекса.

Это почему это?
Нормальное секционированное представление. Констрейнт на ключ, по которому осуществляется секционирование, и создание выровненных индексов, по аналогии с секционированной таблицей - и всё нормально используется.
Разумеется ключ секционирования должен участвовать в запросе.
Второй вариант - таблица одна, но в ней 26 полей. Опять-таки гистограмма будет точная. При этом саму таблицу можно секционировать.
Нет это не тот случай.
...
Рейтинг: 0 / 0
Как биективно отобразить множество на ряд целых чисел, как можно компактнее?
    #40050713
uaggster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Владислав Колосов, см. статистику по regstamp_bin
...
Рейтинг: 0 / 0
Как биективно отобразить множество на ряд целых чисел, как можно компактнее?
    #40050719
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
uaggster,

по regstamp_int плотность 6.95E-4, по regstamp_bin вдвое выше: 13.8E-4. (Почему?)
1/1437 не ~0.00006, а ~0.0006
...
Рейтинг: 0 / 0
Как биективно отобразить множество на ряд целых чисел, как можно компактнее?
    #40050770
uaggster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Владислав Колосов,
Это я нолик перекрутил, когда ответ печатал. :)
На картинке видно.

Для поля regstamp_int - плотность 1/1437, а для _bin - вдвое выше, не смотря на то, что это одно и то же число, в бинарном представлении.
...
Рейтинг: 0 / 0
Как биективно отобразить множество на ряд целых чисел, как можно компактнее?
    #40050790
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
uaggster,

есть запрос, которым это можно смоделировать? Неохота самому писать :)
...
Рейтинг: 0 / 0
Как биективно отобразить множество на ряд целых чисел, как можно компактнее?
    #40051258
Gerros
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
uaggster
Плюс ко всему, если запрос затрагивает несколько секций представления - сервер ошибается (в нашем случае) - еще фатальнее.
Вы изначально в качестве примера целевого запроса приводили
Код: sql
1.
select * from tbl where x = x4

Такой запрос в принципе не может затрагивать больше одной секции. По крайней мере в том варианте секционирования, который предложил я.
Если у Вас другие целевые запросы, можете привести пример?
...
Рейтинг: 0 / 0
15 сообщений из 40, страница 2 из 2
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Как биективно отобразить множество на ряд целых чисел, как можно компактнее?
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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