Комментарии 40
Какой-то адовый автоперевод. На русском читать это тяжело
Таблица-куча. Какие есть варианты?
Еще нужно будет постараться адаптировать это решение к таблицам где в качестве первичного ключа Guid.
Понятно что это не вариант для классической СУБД. В их случае близким аналогом будет пожалуй шардирование. Если вы распараллелить чтение миллиарда записей по железкам можете — вы прочитаете их быстрее. Так что вопрос будет уже в обработке и ее распараллеливании.
У автора в таблице был индекс primary key, и записи не пишутся прошедшей датой. И он косвенным путем нашел крайние ID записей для нужных дат.
Ясненько-понятненько.
А теперь пусть сделает это в таблице, где нет PK.
Откуда взялась такая таблица в БД? Это вопрос уже к разработчикам, в другом городе.
Даже в innodb если его нет, то он есть "Every InnoDB table has a PRIMARY KEY. If you do not provide one, then the first non-NULL UNIQUE key is used. If that can't be done, then a 6-byte, hidden, integer is provided. "
Мы просто кроме mysql давно уже ни с чем не работали, любопытно.
Не знакомы с ms sql, но все же — а разве есть сейчас современные sql движки, где нет PK в принципе?
Да. В MS SQL, если PK нет, его нет. Таблица будет кучей.
Ну наверное, да. Я уже не помню, как там точно детали устроены, но создать таблицу без PK (как явного так и неявного) точно было можно.
Вы правы, PK и кластерный индекс-это не одно и тоже.
Можно создать таблицу как без PK, так и без кластерного индекса, так и без того и другого.
Однако, рекомендуется для всех таблиц (кроме быть может небольших временных, постоянно меняющихся) определять кластерный индекс.
Бинарный поиск это отлично если данные полностью отсортированы. Вот только они не отсортированы. Даже несмотря на то что записи не пишутся задним числом нету ни какой гарантии что даты будут монотонно возрастать. Если не стыке дня/секунды два инсерта в базу прилетят одновременно даты вполне себе могут оказаться в неправильном порядке. ИМХО тут бага
… а в этой таблице правда нет индекса, никакого?
P.S. Но зато там есть партиционирование, например.
Я знаю, что вообще бывают.
По логу лучше отдельно выделить и проиндексировать те поля, по которым оперативно происходит поиск данных. Напр, дата и время события.
А проиндексировать условный терабайт-другой — это во-первых, работа, а во-вторых, индекс тоже займет место. Так что не факт, что индексы вообще всегда нужны.
Потому что по логу если понадобится искать, то будет очень больно, если нет индекса, а строить его-это время, которое может выйти боком бизнесу в простое (пока найдут причину)-это раз.
А во-вторых, если нет кластерного индекса у таблицы особенно большой, то доступ к данным будет через треш, а именно почти всегда через блок всей таблицы и скану всей таблицы.
Почему бы сразу не заложить кластерный секционированный индекс, тем более это несложно.
вот именно что если… С тем же успехом в случае инцидента раз в год можно один раз и просканировать все. Партиционированное — и подавно.
Одного раза хватит, чтобы в лучшем случае уволили, а в худшем, бизнес загнулся.
Вообще о чём.
Ни раз логи в гигабайты и терабайты как раз секционировал по дате, и скорость существенно выше при доступе к данным, чем без секционирования, т к секции позволяют с одной стороны минимизировать блокировки, а с другой-запустить асинхронный поиск в нескольких секциях при необходимости.
P.S.: лучше использовать слово секционирование, т к партиционирование-это недоперевод от partition.
Каждый раз людям предлагаю, купите уже нормальный игровой комп вместо сервера, это будет другая статья расхода в бюджете и купят быстрее… полгода уже покупают.
Ну, это как поглядеть. Следите за руками, как говорится :) Это хорошо, когда у вас данных всего 10 терабайт. А когда их становится 10 петабайт, возникают те же самые в общем проблемы, просто в профиль — когда в общем чатике задают вопросы типа: «Какая сволочь потребила 10000 ядер на кластере, и уже два часа их не отдает?».
Причем как вы понимаете, это не обязательно будет 10 петабайт одним куском — это просто будет 1000 штук по чуть-чуть. Все равно оно упирается в проблемы масштабирования — просто в другом месте.
— на одном сервере на диске свободно 200 Гб, и это мало-мало-надо-срочно-что-то-делать.
— на другом сервере на диске свободно 200 Мб, и этого хватит еще на пару лет.
У Вас было 10 пегабайт?
А что за проект?
Просто не встречал системы, где одно хранилище или одна база данных была бы больше 500 ТБ.
И потом, там же уровень репликации 3 по умолчанию, так что если считать диски — то будет скажем 30, а не 10. В общем, в зависимости от того, какой линейкой мерять, будет получаться разное значение.
Это платформа для аналитики, так что на вопрос откуда это берется, могу сказать без деталей, что отовсюду. Сколько там из одного источника — я могу только примерно прикинуть, но думаю что 500Тб это близко к реальности.
И это без логов приложений, которые могут слать свои портянки.
Другой вопрос, что никто их не хранит больше пары месяцев.
Большое заблуждение, что при больших объемах оперативки, индексы не нужны.
Индексы ещё быстрее позволят информацию вытащить и не занимать лишний раз объемы ОЗУ, которые нужны для оперативных запросов реального времени.
Да и не у всех такие объемы есть по ОЗУ.
В любом случае DBA платят за то, чтобы система не падала, а архитектору-чтоды система работала на любом "говне из палок"
Там в любом случае будет немного жрать ресурсов даже если нет кластерного индекса. Но лучше, когда есть правила на как хранить данные, чем когда система как-то хранит данные.
С другой стороны, если потом таблица вся выгружается куда-то и потом уже там проводится анализ, тогда возможно кластерный индекс и не нужен.
Но лучше провести сравнение при вставках в большую таблицу и посмотреть разницу-где будет быстрее вставляться с кластерный индексом или без.
У меня получалось, что в 100+ млн строк вставка с кластерный индексом была быстрее, чем без кластерного индекса. Однако, если записей всего несколько тысяч или десятков тысяч, то наоборот-вставка в таблицу без кластерного индекса была быстрее, чем с кластерным.
Что они делают, когда у них шифруется все, или последний диск помирает, для меня загадка.
Это частный случай, хотя и достаточно распространённый (когда таблица имеет свой суррогат, и при этом фиксируется ещё и дата/время создания записи). Если выбирать записи нужно по диапазону дат (особенно «отчетных» — месяц/квартал/год), можно сделать computed persisted колонку с формулой вида convert(date, ‘1/‘ + month(date_created) + ‘/‘ + year(date_created)) и по этой колонке уже построить индекс. Но он все равно будет огромный, так как SQL не знает, что в данном конкретном случае отображение create_date -> id сурьективно и неубывающе.
Знает это только человек-разработчик, поэтому для обслуживания этой большой таблицы он может построить рядом маленькую (и заполнять ее джобом по мере того, как наполняется большая таблица): month_date | min_ID | max_ID — тогда по ней можно будет сразу выбрать диапазон ID, соответствующий граничным датам, и затем уже выбрать данные из основной через clustered index seek / key lookup
В вашей непрерывной последовательной последовательности перевода пропущен абзац с числами 30 и 500 000 000 на который осталась ссылка. А там, между прочим, на оригинального автора снизошло озарение, что идентификатор и дата связаны. Поэтому можно использовать бинарный поиск, который далее в статье и расписывается.
Быстрый поиск без индекса