Как стать автором
Обновить

Комментарии 40

Какой-то адовый автоперевод. На русском читать это тяжело

а теперь такой же челлендж, только если вообще нету столбца ID с первичным индексом.
Таблица-куча. Какие есть варианты?
Не знаю, наверное никаких.
Еще нужно будет постараться адаптировать это решение к таблицам где в качестве первичного ключа Guid.
Посмотрите например на Hadoop/Hive. Пожалуй в большинстве случаев там индексов нет (в старых версиях они просто не поддерживались).

Понятно что это не вариант для классической СУБД. В их случае близким аналогом будет пожалуй шардирование. Если вы распараллелить чтение миллиарда записей по железкам можете — вы прочитаете их быстрее. Так что вопрос будет уже в обработке и ее распараллеливании.
Краткое содержание.
У автора в таблице был индекс primary key, и записи не пишутся прошедшей датой. И он косвенным путем нашел крайние ID записей для нужных дат.
Ясненько-понятненько.
А теперь пусть сделает это в таблице, где нет PK.
Откуда взялась такая таблица в БД? Это вопрос уже к разработчикам, в другом городе.
Не знакомы с ms sql, но все же — а разве есть сейчас современные sql движки, где нет 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 нет, его нет. Таблица будет кучей.

Не придирки ради, разве не clustered index определяет то, является ли таблица кучей? Соответственно, можно создать таблицу с PK, но без индекса и наоборот.

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

Вы правы, PK и кластерный индекс-это не одно и тоже.
Можно создать таблицу как без PK, так и без кластерного индекса, так и без того и другого.
Однако, рекомендуется для всех таблиц (кроме быть может небольших временных, постоянно меняющихся) определять кластерный индекс.

Бинарный поиск это отлично если данные полностью отсортированы. Вот только они не отсортированы. Даже несмотря на то что записи не пишутся задним числом нету ни какой гарантии что даты будут монотонно возрастать. Если не стыке дня/секунды два инсерта в базу прилетят одновременно даты вполне себе могут оказаться в неправильном порядке. ИМХО тут бага

… а в этой таблице правда нет индекса, никакого?

Не знаю как в этой, но вообще такие бывают, да. Таблица — лог, для аудита, типовой пример. Там даже есть поле ID — но оно заполняется из sequence, и индекса по нему реально нет.

P.S. Но зато там есть партиционирование, например.

Я знаю, что вообще бывают.

По логу лучше отдельно выделить и проиндексировать те поля, по которым оперативно происходит поиск данных. Напр, дата и время события.

Вообще-то, по этой таблице возможно никогда не ищут. Зачем искать по логу аудита, если все нормально? Это аудит на случай инцидентов.

А проиндексировать условный терабайт-другой — это во-первых, работа, а во-вторых, индекс тоже займет место. Так что не факт, что индексы вообще всегда нужны.

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

>Потому что по логу если понадобится искать,
вот именно что если… С тем же успехом в случае инцидента раз в год можно один раз и просканировать все. Партиционированное — и подавно.

Одного раза хватит, чтобы в лучшем случае уволили, а в худшем, бизнес загнулся.

Вы слово партиционированный видели? Терабайт с партиционированием по дате — это может быть всего пара гигов в сутки, что есть вообще ни о чем.

Вообще о чём.
Ни раз логи в гигабайты и терабайты как раз секционировал по дате, и скорость существенно выше при доступе к данным, чем без секционирования, т к секции позволяют с одной стороны минимизировать блокировки, а с другой-запустить асинхронный поиск в нескольких секциях при необходимости.
P.S.: лучше использовать слово секционирование, т к партиционирование-это недоперевод от partition.

Не знаю, что у вас там за железки, у нас типовой узел кластера имеет полтерабайта оперативки. Поэтому даже терабайтовая таблица — это вообще ничто, ее два-три узла спокойно читают в память, и делают там что угодно и как угодно. Какие-то проблемы возможны примерно на два порядка позже — при объемах порядка 10 терабайт в сутки.
Хорошо у вас там. А в народе 32ГБ ОЗУ, 400Гб база, и дохлый недоRAID с временем ожидания до 10 секунд.
Каждый раз людям предлагаю, купите уже нормальный игровой комп вместо сервера, это будет другая статья расхода в бюджете и купят быстрее… полгода уже покупают.
>Хорошо у вас там.
Ну, это как поглядеть. Следите за руками, как говорится :) Это хорошо, когда у вас данных всего 10 терабайт. А когда их становится 10 петабайт, возникают те же самые в общем проблемы, просто в профиль — когда в общем чатике задают вопросы типа: «Какая сволочь потребила 10000 ядер на кластере, и уже два часа их не отдает?».

Причем как вы понимаете, это не обязательно будет 10 петабайт одним куском — это просто будет 1000 штук по чуть-чуть. Все равно оно упирается в проблемы масштабирования — просто в другом месте.
Ну это понятно, сам однажды смеялся над ситуацией, когда в один момент времени было:
— на одном сервере на диске свободно 200 Гб, и это мало-мало-надо-срочно-что-то-делать.
— на другом сервере на диске свободно 200 Мб, и этого хватит еще на пару лет.

У Вас было 10 пегабайт?
А что за проект?
Просто не встречал системы, где одно хранилище или одна база данных была бы больше 500 ТБ.

У нас есть примерно 10 петабайт. Я думаю даже больше — но это не совсем корректно считать одним хранилищем, потому что это на самом деле несколько хадуп кластеров. Их можно объединить, теоретически, чтобы выглядело как один — но думаю проблемы масштабирования при этом вылезут по полной программе.

И потом, там же уровень репликации 3 по умолчанию, так что если считать диски — то будет скажем 30, а не 10. В общем, в зависимости от того, какой линейкой мерять, будет получаться разное значение.

Это платформа для аналитики, так что на вопрос откуда это берется, могу сказать без деталей, что отовсюду. Сколько там из одного источника — я могу только примерно прикинуть, но думаю что 500Тб это близко к реальности.
Логи с пары десятков серверов за год будут занимать чуть меньше терабайта в Elasticsearch.
И это без логов приложений, которые могут слать свои портянки.
Другой вопрос, что никто их не хранит больше пары месяцев.

Видел размеры логов от десятков тысяч серверов с приложениями, выходило около 10 ТБ в год. И да, обычно годами все логи не хранят, периодически делая чистку.

Большое заблуждение, что при больших объемах оперативки, индексы не нужны.
Индексы ещё быстрее позволят информацию вытащить и не занимать лишний раз объемы ОЗУ, которые нужны для оперативных запросов реального времени.
Да и не у всех такие объемы есть по ОЗУ.
В любом случае DBA платят за то, чтобы система не падала, а архитектору-чтоды система работала на любом "говне из палок"

Я никогда не говорил, что они не нужны. Я говорю, что 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

Только обычно проблема в том, что таблица уже есть, а индекса еще нет.
А бонусом идет то, что индекс на текущей БД нельзя построить в онлайне (у MS SQL редакция не та), а в ночное окно мы не успеваем, потому что замену сервера не заложили в прошлогодний бюджет.

В вашей непрерывной последовательной последовательности перевода пропущен абзац с числами 30 и 500 000 000 на который осталась ссылка. А там, между прочим, на оригинального автора снизошло озарение, что идентификатор и дата связаны. Поэтому можно использовать бинарный поиск, который далее в статье и расписывается.

Спасибо! Добавил потерянный абзац.
Зарегистрируйтесь на Хабре , чтобы оставить комментарий

Публикации

Истории