|
Как биективно отобразить множество на ряд целых чисел, как можно компактнее?
|
|||
---|---|---|---|
#18+
... и так, чтобы полученный ряд хорошо ложился в статистики sqlserver. Сломал голову. Решить не в состоянии, так как теорию вопроса уже забыл (да еще и не знал). Помогите! Имеется некий набор значений, (n, m, k), который нужно отобразить на ряд целых чисел. Набор значений k - может меняться, он монотонно растет (очень медленно) Набор значений n, m - всегда неизменен. Код: 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.
Необходимо нарисовать некую функцию x=F(n, m, k), набор х значений которой удовлетворял бы следующим свойствам: 1. Каждому значению (n, m, k) должно соответствовать одно и только одно значение х, и каждому значению х должно соответствовать одно и только одно значение (n, m, k). 2. Набор значений х должен хорошо ложиться в правила формирования статистик mssqlserver, причем преимущественно адекватно должно оцениваться количество наборов с одинаковым k. Т.е. наборы значений с одинаковым k должны ложиться примерно в один персентиль значений x, с т.з. формирования статистик mssqlserver. 3. Значения x, соответствующие одному k - должны быть интервальными, и не пересекающимися с другими значениями х наборов с другим k. Т.е. всему множеству (n, m, 60) должен соответствовать некий интервал значений х, например 1...1000, причем никакому другому значению k тот же интервал соответствовать не должен. Т.е. ситуация, когда k = 60 соответствуют значения 1, 3, 5... а k=59 - 2, 4, 6 - недопустима. 4. Набор значений х должен быть максимально компактным. Вместе с тем условия непрерывности на ряд значений х - не накладывается. Т.е., совершенно необязательно, чтобы значения х шли без разрывов и max(x) - min(x) = 5124. Требуется лишь чтобы по этому набору хорошо строилась статистика, см. п.2. 5. Предположим, у нас есть таблица n, m, k, x рассчитанная. Значений: 0, 0, 60, х1 - 100 0, 1, 60, х2 - 1 млн. 1, 0, 60, х3 - 1 2, 0, 60, х4 - 10 тыс. Оптимизатор, при запросе select * from tbl where x = x4 - должен или адекватно оценивать количество строк (10 тыс.), либо полагать их ~ 1 млн. Возможно, я задаю чересчур жесткие условия, но пока не получается сформулировать с меньшим количеством ограничений... ... |
|||
:
Нравится:
Не нравится:
|
|||
24.02.2021, 18:57 |
|
Как биективно отобразить множество на ряд целых чисел, как можно компактнее?
|
|||
---|---|---|---|
#18+
Вот ведь великие тиоретики... Код: sql 1.
... |
|||
:
Нравится:
Не нравится:
|
|||
24.02.2021, 19:18 |
|
Как биективно отобразить множество на ряд целых чисел, как можно компактнее?
|
|||
---|---|---|---|
#18+
aleks222, Неа, не подходит. Оно не дает int на выходе. ... а хотелось бы вообще smallint, но это мечты. И гистограмма будет дырявая. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.02.2021, 07:41 |
|
Как биективно отобразить множество на ряд целых чисел, как можно компактнее?
|
|||
---|---|---|---|
#18+
А у этих n, m, k какие-то пределы есть? никто ж не мешает просто перевести число nmk в десятичную систему счисления. И, раз значения для какой-то переменной, скажем, k, должны лежать плотно - значит. её в старший разряд. Применительно к показанным значениям, это может быть kmn и, соответственно, (k*12*7 + m*7 + n). ... |
|||
:
Нравится:
Не нравится:
|
|||
25.02.2021, 08:30 |
|
Как биективно отобразить множество на ряд целых чисел, как можно компактнее?
|
|||
---|---|---|---|
#18+
uaggster aleks222, Неа, не подходит. 1. Оно не дает int на выходе. ... а хотелось бы вообще smallint, но это мечты. И гистограмма будет дырявая. 1. Учиться надо, студент. 2. А чо бы не в bit? ... |
|||
:
Нравится:
Не нравится:
|
|||
25.02.2021, 09:33 |
|
Как биективно отобразить множество на ряд целых чисел, как можно компактнее?
|
|||
---|---|---|---|
#18+
aleks222 uaggster aleks222, Неа, не подходит. 1. Оно не дает int на выходе. ... 2. а хотелось бы вообще smallint, но это мечты. И гистограмма будет дырявая. 1. Учиться надо, студент. 2. А чо бы не в bit? ... |
|||
:
Нравится:
Не нравится:
|
|||
25.02.2021, 09:34 |
|
Как биективно отобразить множество на ряд целых чисел, как можно компактнее?
|
|||
---|---|---|---|
#18+
Akina А у этих n, m, k какие-то пределы есть? никто ж не мешает просто перевести число nmk в десятичную систему счисления. И, раз значения для какой-то переменной, скажем, k, должны лежать плотно - значит. её в старший разряд. Применительно к показанным значениям, это может быть kmn и, соответственно, (k*12*7 + m*7 + n). Фактически, переделы как раз и озвучены. Количество k может увеличиться на ~10 за несколько лет, количество значений n - на пару-тройку за несколько лет (но можно считать статическим). Указанный алгоритм не подходит, интервалы получаются не-непрерывные по k, см. п.3. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.02.2021, 09:38 |
|
Как биективно отобразить множество на ряд целых чисел, как можно компактнее?
|
|||
---|---|---|---|
#18+
aleks222 uaggster aleks222, Неа, не подходит. 1. Оно не дает int на выходе. ... а хотелось бы вообще smallint, но это мечты. И гистограмма будет дырявая. 1. Учиться надо, студент. 2. А чо бы не в bit? К сожалению, студентом я был 30 лет назад :-( В bit - хотелось бы, но, к сожалению 5 тыс. значений в трех измерениях в него не поместятся. Размер имеет значение. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.02.2021, 09:43 |
|
Как биективно отобразить множество на ряд целых чисел, как можно компактнее?
|
|||
---|---|---|---|
#18+
Подоплека задачи: Имеется таблица, примерно на миллиард записей. Каждую запись можно охарактеризовать группой из 3 признаков, в итоге - см. выше. Хочется сопоставить этим признакам некое число, и использовать его: 1. Как ключ при разбиении на секции 2. Как хеширующий признак при выборках. Именно поэтому важна интервальность, прежде всего - по k, но желательно еще и по n Сейчас ключ строится как: k*10000 + n * 1000 + m Но у него совершенно жуткая статистика! Размах значений в 60 тыс, причем значения разбросаны очень неравномерно. В результате MSSQLSERVER строит совершенно жуткую гистограмму по этому полю. Как результат оптимизатор периодически или ударяется в сканирование всего, или рисует нестед лупы, полагая, что для какого-то значения мало записей. А количество записей с каждым признаком - действительно неравномерное. От 0 до 20-30 млн. Собственно, поэтому и задача. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.02.2021, 10:16 |
|
Как биективно отобразить множество на ряд целых чисел, как можно компактнее?
|
|||
---|---|---|---|
#18+
uaggster aleks222 пропущено... 1. Учиться надо, студент. 2. А чо бы не в bit? К сожалению, студентом я был 30 лет назад :-( В bit - хотелось бы, но, к сожалению 5 тыс. значений в трех измерениях в него не поместятся. Размер имеет значение. Прогуливал, нибось. uaggster Подоплека задачи: Имеется таблица, примерно на миллиард записей. Каждую запись можно охарактеризовать группой из 3 признаков, в итоге - см. выше. Хочется сопоставить этим признакам некое число, и использовать его: 1. Как ключ при разбиении на секции 2. Как хеширующий признак при выборках. Именно поэтому важна интервальность, прежде всего - по k, но желательно еще и по n Сейчас ключ строится как: k*10000 + n * 1000 + m Но у него совершенно жуткая статистика! Размах значений в 60 тыс, причем значения разбросаны очень неравномерно. В результате MSSQLSERVER строит совершенно жуткую гистограмму по этому полю. Как результат оптимизатор периодически или ударяется в сканирование всего, или рисует нестед лупы, полагая, что для какого-то значения мало записей. А количество записей с каждым признаком - действительно неравномерное. От 0 до 20-30 млн. Собственно, поэтому и задача. Я фантазий бесплодных люблю громадье... Ну вставь все свои уникальные k, n, m во вспомогательную таблицу с identity. Получишь соответствие ( k, n, m ) -> id И пользуй это id. ЗЫ. Изобретение непромокаемого пороха на марше. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.02.2021, 10:22 |
|
Как биективно отобразить множество на ряд целых чисел, как можно компактнее?
|
|||
---|---|---|---|
#18+
aleks222 Ну вставь все свои уникальные k, n, m во вспомогательную таблицу с identity. Получишь соответствие ( k, n, m ) -> id И пользуй это id. ЗЫ. Изобретение непромокаемого пороха на марше. Плохая идея. k и n - могут измениться. При этом все признаки пересчитывать? Т.е. последовательность целых чисел - неустойчиво к изменению количества признаков. Кроме того - проблемы со статистикой оно никак не решает. Нужно, чтобы статистика MSSQLSERVER адекватно оценивало количество значений, которое хотя бы соответствует одному k Т.е., фиг с ним, пусть промахивается при оценке количества для конкретного значения ( k, n, m ). Но пусть оценивает его хотя бы соответствующим количеству значений с определенным k. А непромокаемый порох давно изобретен. В виде унитарного патрона :-) ... |
|||
:
Нравится:
Не нравится:
|
|||
25.02.2021, 10:54 |
|
Как биективно отобразить множество на ряд целых чисел, как можно компактнее?
|
|||
---|---|---|---|
#18+
[quot uaggster#22286165] aleks222 Кроме того - проблемы со статистикой оно никак не решает. Нужно, чтобы статистика MSSQLSERVER адекватно оценивало количество значений, которое хотя бы соответствует одному k Т.е., фиг с ним, пусть промахивается при оценке количества для конкретного значения ( k, n, m ). Но пусть оценивает его хотя бы соответствующим количеству значений с определенным k. Ну так у вас обычный объект статистики по колонке k и будет иметь гистограмму распределения значений. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.02.2021, 11:35 |
|
Как биективно отобразить множество на ряд целых чисел, как можно компактнее?
|
|||
---|---|---|---|
#18+
felix_ff, да, но оно получается слишком грубым приближением. Я не совсем правильно выразился. Правильнее так: Хочется, чтобы оптимизатор правильно оценивал статистику по (k, n, m). Но уж если по какому то набору это не получается - пусть промахивается, и считает как по диапазону одного значения k, или его подмножеству. Я понимаю, что 5000 значений в 200 интервалов не уместить, но хоть что-то в этом направлении сделать. Кроме того ладно, пусть будет "как по k", только поле нужно всё равно кодирующее все 3 признака, и взаимооднозначно. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.02.2021, 12:55 |
|
Как биективно отобразить множество на ряд целых чисел, как можно компактнее?
|
|||
---|---|---|---|
#18+
uaggster Имеется некий набор значений, (n, m, k), который нужно отобразить на ряд целых чисел. Набор значений k - может меняться, он монотонно растет (очень медленно) Набор значений n, m - всегда неизменен. Это как позиционная система счисления с разным основанимем в каждом разряде. Первым делом надо посчитать справочники для m, k и диапазон для n. Допустим мы знаем что n - bigint (это 2^64 степени). Мощности справочников по m, k - допустим 37 и 61. Тоесть любой тройке (n, m, k) соотвествует уникальное целое число Код: sql 1.
Где M(), K() функции которые декодируют значения m,k (грубо говоря возвращают порядковые номера). (макс. значение этого отображения будет даже больше чем bigint (2^64 * 37 * 61)) По другим твоим пожеланиям по статистике - сложно... Надо думать. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.02.2021, 14:16 |
|
Как биективно отобразить множество на ряд целых чисел, как можно компактнее?
|
|||
---|---|---|---|
#18+
mayton, Ненене! Избыточно. Возможные значения, собственно, перечислены в исходном запросе. n - максимум 10, сейчас 5, и рост до 10 - в неопределенной перспективе, можно этим пренебречь. k - 60, максимум - 100 значений. m - в точности 12 (точнее, 11 и "прочее", так что 12). Итого в ключе менее 10 тыс. вариантов. И всё это нормально влазит в smallint. Проблема то как раз в том, чтобы сконструировать это значение таким образом, чтобы по нему нормально создавалась статистика. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.02.2021, 15:25 |
|
Как биективно отобразить множество на ряд целых чисел, как можно компактнее?
|
|||
---|---|---|---|
#18+
uaggster, чет я пока не понимаю тогда цели которую вы преследуете. у вас написано что комбинация (n,m,k) дает всегда уникальное значение. вам было предложено в виде "хеш-функции" взять бинарное представление, статистика по столбцу binary тоже строится нормально. Код: 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.
... |
|||
:
Нравится:
Не нравится:
|
|||
25.02.2021, 16:12 |
|
Как биективно отобразить множество на ряд целых чисел, как можно компактнее?
|
|||
---|---|---|---|
#18+
felix_ff, вам было предложено в виде "хеш-функции" взять бинарное представление, статистика по столбцу binary тоже строится нормально. На маленьких примерах - всё замечательно работает. Теперь представьте, что ключей ~ 5000, а количество входов по каждому ключу - от 1 (единицы) до 20 млн. В среднем - порядка миллиона, но очень неровно. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.02.2021, 16:34 |
|
Как биективно отобразить множество на ряд целых чисел, как можно компактнее?
|
|||
---|---|---|---|
#18+
uaggster mayton, Ненене! Избыточно. Возможные значения, собственно, перечислены в исходном запросе. n - максимум 10, сейчас 5, и рост до 10 - в неопределенной перспективе, можно этим пренебречь. k - 60, максимум - 100 значений. m - в точности 12 (точнее, 11 и "прочее", так что 12). Итого в ключе менее 10 тыс. вариантов. И всё это нормально влазит в smallint. Проблема то как раз в том, чтобы сконструировать это значение таким образом, чтобы по нему нормально создавалась статистика. Почему избыточно? Покажи на практике. По поводу хешей. Это - самый простой способ отображения - но оно не будет биективно. Тогда надо менять заголовок этого топика. По поводу "нормально создавалась статистика". Я не спец в MS-SQL. Я - больше по Oracle. Но мне не совсем понятно какую цель ты преследуешь. Я тебе дал абсолютно точную и однозначную формулу. Биекция. Работает в обе стороны. Отображает точку в трехмерном пространстве на число. Компактное. Я писал о справочниках а не об оригинальных значениях. Возможно в MS-SQL есть какая-то технология которая по данному целому числу может извлекать знания из гистограмм. Но мне этот подход кажется сомнительным. Вместо трех гистограмм - у нас будет одна. Сложная. С пульсациями. Что дальше с ней сделает MSSQL? ХЗ. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.02.2021, 16:49 |
|
Как биективно отобразить множество на ряд целых чисел, как можно компактнее?
|
|||
---|---|---|---|
#18+
mayton, Возможно в MS-SQL есть какая-то технология которая по данному целому числу может извлекать знания из гистограмм. Но мне этот подход кажется сомнительным. Вместо трех гистограмм - у нас будет одна. Сложная. С пульсациями. Что дальше с ней сделает MSSQL? ХЗ. В том то и дело что ничего. Если ТС хочет добиться поведения при котором оптимизатор посмотрев объект статистики по любому ключу будет ему выдавать оценку как если бы бы этот самый ключ представлял RANGE_HIGH_KEY значение - то хер. Лимит шагов в гистограмме 200. точное число строк выдается в виде EQ_ROWS если запрашивается ключ попадающий в RHK. в случаях если в интервале лежат несколько ключей в расчет будет идти значение AVG_RANGE_ROWS, при этом если в интервале наблюдается сильная дисперсия значений то увы здесь ничего не поделаешь. здесь только создавать фильтрованные статистики для большей детализации, но автоматом сиквел такую ситуацию не разрулит. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.02.2021, 17:14 |
|
Как биективно отобразить множество на ряд целых чисел, как можно компактнее?
|
|||
---|---|---|---|
#18+
felix_ff mayton, Возможно в MS-SQL есть какая-то технология которая по данному целому числу может извлекать знания из гистограмм. Но мне этот подход кажется сомнительным. Вместо трех гистограмм - у нас будет одна. Сложная. С пульсациями. Что дальше с ней сделает MSSQL? ХЗ. В том то и дело что ничего. Если ТС хочет добиться поведения при котором оптимизатор посмотрев объект статистики по любому ключу будет ему выдавать оценку как если бы бы этот самый ключ представлял RANGE_HIGH_KEY значение - то хер. Лимит шагов в гистограмме 200. точное число строк выдается в виде EQ_ROWS если запрашивается ключ попадающий в RHK. в случаях если в интервале лежат несколько ключей в расчет будет идти значение AVG_RANGE_ROWS, при этом если в интервале наблюдается сильная дисперсия значений то увы здесь ничего не поделаешь. здесь только создавать фильтрованные статистики для большей детализации, но автоматом сиквел такую ситуацию не разрулит. Ага, примерно этого и хочу, и понимаю, что это - невозможно. Я понимаю, что 5000 уникальных ключей на 200 интервалов - не отобразишь. И фильтрованная статистика - не годиться, т.к. она не бывает инкрементальной, а нужна именно инкрементальная. Я хочу таким образом подобрать значения ключей, чтобы: 1) 1 ключу соответствовал один и только один набор этих трех параметров (n, m, k) 2) При построении статистики по записям с такими ключами статистика вела бы себя, в худшем случае, как построенная по полю k (60 уникальных входов, и в 200 шаговую диаграмму - замечательно укладывается целиком), но, возможно с несколько большей детализацией (т.к. значений k - 60, а шагов в гистограмме - в 3,5 раза больше). 3) При этом чтобы значение ключа было целым числом, а лучше smallint, ибо дорого. И 4) Можно было достоверно сказать, что диапазон ключа between x1 and x2 - относится к одному и только одному значению k. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.02.2021, 18:14 |
|
Как биективно отобразить множество на ряд целых чисел, как можно компактнее?
|
|||
---|---|---|---|
#18+
Мне кажется что тут была неверная постановка. Гистограммы никогда точно и не отражают исходные данные. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.02.2021, 18:33 |
|
Как биективно отобразить множество на ряд целых чисел, как можно компактнее?
|
|||
---|---|---|---|
#18+
uaggster, зачем вам инкрементальная? ее гистограммы не используется CE для оценки кол-ва строк. фишка инкрементальной статистики только в том что бы облегчить жизнь админам, дабы уменьшить время окна обслуживания и расход ресурсов на поддержание актуальной статистики. адд: и да, соглашусь с mayton. не имеет смысла гнаться за стопроцентно точной оценкой по гистограммам. потратите больше времени и сил. можно бороться с какой то конкретной "плохой" оценкой, но это обычно лечится тюнингом запросов нежели изобретением магической палочки ... |
|||
:
Нравится:
Не нравится:
|
|||
25.02.2021, 18:39 |
|
Как биективно отобразить множество на ряд целых чисел, как можно компактнее?
|
|||
---|---|---|---|
#18+
Идея с вычислением хэш не такая уж и плохая. Это хэш можно положить в основу секционирования таблицы, в этом случае компилятор будет иметь довольно точное представление о количестве записей в секции. Я так предполагаю. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.02.2021, 18:43 |
|
Как биективно отобразить множество на ряд целых чисел, как можно компактнее?
|
|||
---|---|---|---|
#18+
Владислав Колосов Идея с вычислением хэш не такая уж и плохая. Это хэш можно положить в основу секционирования таблицы, в этом случае компилятор будет иметь довольно точное представление о количестве записей в секции. Я так предполагаю. А именно так и сделано уже . Просто ключ выбран, как мне видится - очень неудачно. Сейчас он считается как: k*10000 + n * 1000 + m И это приводит к тому, что набор значений ключа очень "полосатый". Разброс между минимальным значением и максимальным - 600 тыс., и значения ключа, которые соответствуют реальным координатам (n,m,k) - очень "островковые". Это приводит к тому, что mssqlserver не может построить по нему адекватную гистограмму. Например, выпадают и неверно оцениваются промежутки, соответствующие некоторым k, и он начинает оценивать количество значений, как количество между неким k-3 и k+5 (например), что совсем не в ту степь, т.к., напоминаю, речь идет о миллионах записей. Поэтому и хочется как то изменить алгоритм построения ключа, чтобы он стал статистически более равномерным, и гистограмма по нему выглядела, ну, как построенная по k в первом приближении. Или чуть более детально, чем по k (в k, напоминаю, 60 уникальных значений, и возможен рост до 100, но не более и не мгновенно, когда-нибудь, короче). felix_ff статистика должна быть инкрементальной, т.к. таблица пополняется подменой секций. Если на таблице имеется не-инкрементальная статистика - выполнить switch partition не получится. Я вот думаю, может ключ сделать char(4) и кодировать его значения в 16 или, скажем, 32-ричной системе? ... |
|||
:
Нравится:
Не нравится:
|
|||
26.02.2021, 07:53 |
|
|
start [/forum/topic.php?fid=46&fpage=32&tid=1684997]: |
0ms |
get settings: |
10ms |
get forum list: |
14ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
60ms |
get topic data: |
13ms |
get forum data: |
3ms |
get page messages: |
60ms |
get tp. blocked users: |
2ms |
others: | 15ms |
total: | 183ms |
0 / 0 |