Pull to refresh

Comments 20

По сути:

1. Чтобы этот пункт стал правилом, нужно ввести критерий, при каких объемах и в каких СУБД это делать. Например при малых объемах обычные b-древовидные индевсы великолепно справляются, а для Oracle есть механизм партишенов, когда таблица логически одна, а физически данные хранятся в отдельных таблицах — download.oracle.com/docs/cd/B28359_01/server.111/b32024/partition.htm Ну и, конечно же, лучше рассмотреть еще и проблемы, которые такое разделение по таблицам принесет и методы решения. Например, запросы, где нужно будет выбрать несколько записей и этот самый «простой признак» будет разный, придется клеить с помощью UNION. Если большинство запросов к таблице будут включать этот «простой признак», то хорошо, а если будут большие выборки и часто без него, то производительность может упасть.

3. Нельзя не согласиться, то как это относится к СУБД?

Еще подброшу идеи для проработки:

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

6. Если есть возможность, используйте паматерические запросы и PREPARE

7. Группируйте все короткие NOT NULL поля ближе к началу записи в таблице, например, сначала все FOREIGN KEY, потом все типы с фиксированной длиной, из них сначала INTEGER и все более короткие, потом char, и уж потом varchar, после них идут NULLABLE-поля в таком же порядке и в самом конце TEXT/BLOB и т.д.
1) вы берете на себя то, что должна брать БД
2) в большинстве случаев см. п. 1 т.к. зачем использовать файлы, если большая нагрузка, используйте БД, которая позволяет хранить данные такого типа.
3) а чем собственно плох мемкэш? или хранилища построенные на тех же деревьях. Всегда нужно смотреть на готовые решения, а только затем велосипедить, если уж иначе никак.
4) очень специфичный совет…

В общем, набор каких-то странных мыслей, которые можно применить в каких-то редких частных случаях.
Ниже я ответил про 2,3
А по поводу я беру на себя — так это и есть Ваша работа, если за день работы по оптимизации например большой системы статистики можно не ставить новый сервер, а освободить существующий на 90% — это того стоит. Сам имею 8 серверов и под 70 тыс хостов в день + счетчик посещений который обсчитывает пару лямов хитов, и поверьте что MySQL + все эти несложные трюки позволяют легко решать проблемы загрузки
Я соглашусь с вами, но название действительно хотелось бы переформулировать. Как-нибудь типа «Методы оптимизации производительности приложения при работе с РБД».
Спасибо за идею, сидел думал как раз — взял Ваш заголовок :)
1. Во-первых не советовал бы использовать термин «кластеризации». За clustering есть уже устоявшийся процесс. А то, что в оригинале звучит как partitioning, на наш принято переводить как секционирование или партиционирование. Во-вторых, стоило бы отметить, что оно бывает не только вертикальным, как в вашем примере, но и горизонтальным, когда таблица разбивается на две «параллельные» таблицы, каждая из которых содержит свой набор колонок. В-третьих, секционирование дает мало пользы, если не рассказать о преимуществах разнесения партиций по различным физическим хранилищам для обеспечения одновременного доступа, особенно, когда вы используете для секционирования функцию ID%N==I. Будучи примененная к базе на одном диске, она убьет вам сканы и я бы за такое повесил на ближайшем столбе)) Пример, который вы привели с фото, запросто решается кластерными индексами, без секционирования (если только вы не разносите по разным физическим хранилищам).

2. Требование «читать старайся подряд» я разделяю, но «от начала до конца» категорически нет. Читать надо ровно столько, сколько нужно и не записью больше. Надеюсь, все-таки, имелось ввиду в направлении от начала к концу. Я бы сформулировал точнее, что читать надо стараться в порядке физического расположения записей. Кэширование и буферизация записи целиком зависит от политики надежности системы. Вы можете забить, если какая-та надпись на стене в социалке будет потеряна, но если вы похожей тактикой руководствуетесь в ПО для здравоохранения, финансов и т.п., то вас будут ждать неприятности.

3. Вы просто перепели по своему концепцию кэширования. Она ничего общего не имеет с «вопросами построения баз данных», это уровень приложения. Если только вы не используете кэширование внутри базы, как то персистентные поля, материализованные представления и прочие проявления денормализации базы в погоне за производительностью.

4. Таблица с кластерным индексом по коду человека в таблице фоток даст вам ответ на нужный вопрос в течении миллисекунд. А вот как вы собираетесь в информации о самом человек хранить фотки — это вопрос. Может не такой серьезный с точки зрения MongoDB, например, хотя и там есть ограничения. Но хороший вопрос с точки зрения РБД.
1. Не сталкивался с проблемами на 1 диске… Может предел запросов одновременный не переходил…
2. Да, естественно если надо. В своих БД специально проектирую возможность seek к нужной записи и чтобы они лежали подряд
3. Свои БД пишу под конкретные задачи, соответственно и алгоритмы там могу использовать только наиболее эффективные, а не только универсальные
4. Почитаю про кластерные индексы. Всякие деревья кроме AVL не дают ответ достаточно быстро, и все что не Oracle, как-то не очень быстро делает выборку например по индексу в базе с парой миллионов пользователей. Возможно есть стандартное решение, но пока не сталкивался
4. Часто хеш работает быстрее AVL-дерева. Если нет необходимости последовательно пробегать по записям, использую хеш.
Зависит от количества. Если в хеше слишком много альтернатив, то по ним долго бегать. У меня почему-то всегда слишком много :)
Попробуйте гибридный вариант. Индекс (b-дерево) порезать на последовательные куски, а адрес вершины каждого поддерева хранить в хэше. В качестве хэш-ключа можно взять N первых байт базового ключа. Правда длины кусков-веток могут сильно отличаться из-за нелинейного распределения множества значений ключа.
вот тут я рассказываю про AVL дерево которое решает вопросы быстро и просто
habrahabr.ru/blogs/search_engines/123951/
там кстати и другие альтернативы в коментах предлагают.

а сейчас хеш, например по словам в БД, у меня устроен именно так как вы описываете.
В общем, статью нужно серьезно дорабатывать, чтобы ее можно было показать приличным людям, обратить внимание на написанное в коментах, поменять формулировки. И название «Некоторые общие вопросы построения баз данных» не подходит, тут нет общих вопросов, они прекрасно расписаны в теории РБД. Я советую название «Повышение производительности с помощью денационализации БД».
Фу, опечатался, не денационализации, а денормализации, конечно же:
«Повышение производительности с помощью денормализации БД» )))
если про нормализацию то мысль не ясна. БД остается нормализованой, даже более чем была.

К примеру: у половины форумов primary index в таблицах состоит из нескольких полей, чтобы было удобно было делать JOIN для 10 таблиц туда запихнуты все нужные поля — id юзера, группы, топика, и тд… причем все это чтобы выбрать 1 сообщение к примеру — данного юзера в данном топике, да еще и фотку юзера и тд

однако если сделать один код-CRC или даже несколько и выбирать по нему просто последовательно из 10 таблиц то можно получить ту же инфу в 10 раз быстрее. Просто этот код и стоит сделать PRIMARY INDEX заместо того что было

Я уж не говорю что проще было бы сложить все фотки юзеров по их ID: photos/ID_USER.jpg
и вообще не надо было бы делать лишнюю выборку — если отходить от СУБД немного.

Конечно это если это все касалось пункта 4, и я правильно понял
К пункту 4 претензий не имею, подробнее отпишу завтра.
Нормализация РБД — это избавление от дублирующейся информации, чем выше нормальная форма, тем меньше дублирования. Вот в пункте 1 Вы вводите дублирование, одно из полей становится признаком, по которому мы делим таблицы, так что информация из этого поля попадает в имя таблицы, так что дублирование есть, хотя оно и не подпадает под нормальные формы вообще.

Вот в примере выше, Вы пишете, что плохо делать последовательные (я читаю как вложенные) запросы из 10 таблиц и лучше все эти ключи сразу тянуть в «большую» таблицу и делать составной PK. Это и есть избыточность, отход от нормализации. Но это не плохо. Если я правильно понял, то по цепочек мы собираем составной ключ из двух, трех, четырех полей, (например: страна, область, город, улица, дом, жилец), так вот «жилец» может содержать составной ключ их 5 каскажных таблиц, хотя может содержать только ID дома. Конечно, 5 полей в ключе — избыточность, но когда нужно считать статистику по странам и областям, то это даст серьезный прирост в производительности.

Как и везде, правильная денормализация — путь к ускорению.
Пожалуй по поводу названия Вы правы, статья относилась к БД типа mySQL и аналоги. И вообще, почему вы считаете что все ограничивается только реляционными коробочными СУБД?

Вот гугл почему то считает что разделение БД на части называется кластеризацией. Правда было это еще на этапе его создания

Memcache по сравнению с реально работающими в вашей же памяти реально быстрыми алгоритмами (ну просто по книжке тот же Heap) будет отставать на много порядков. Здесь я говорю о приложениях, конечно, немного сложнее чем сайт-визитка

Одним из реально узких мест всех сторонних решений является интерфейс по которому идет передача данных — через сокеты ли, или через IPC

Про реляционки, я как раз так не считаю, лет 12-13 назад я написал собственную СУБД с гибридной моделью данных, которую сам уже лет 6 не запускал, а люди все еще ей пользуются (программисты и клиенты многие). И конечно же поддерживаю Ваше возмущение тем, что нынешний программист в большей массе не понимает что такое, например, двух-связанный список или стек, не может построить в памяти дерево (например пяти-связанное, когда каждый элемент знает своего предка, соседа справа, соседа слева, первого чайлда и последнего чайлда) и вообще такими словами с нынешним поколением, не читавшим Д. Кнута, говорить бесполезно. И это приводит к тому, что повсеместно пишутся софты, без понимания и учета работы с памятью, накопителями, без оглядки на алгоритмы сортировки и индексации. Потом в систему попадает 100 пользователей и все лежит, хотя та же техника выдержит 10 000 одновременно работающих клиентов при правильном подходе.

Какую основную здравую мысль я увидел в статье, и которую советую развивать, ибо ее понимание будет многим полезно: не всегда нужно нормализировать базы и придерживать строгостей нормальных форм, а для повышения производительности, наоборот, часто приходится денормализировать их, хранить дублидующиеся данные, копии данных, агрегированные и подготовленные к чтению данные, принудительно разрезанные данные и т.д. В этом я убедился много раз сам на опыте и идею поддерживаю. Но нужно сказать и о проблемах, что в денормализированной базе нужно точно знать, какие данные есть первичными, а какие излишними, нужно недопустить противоречивых данных, которые всегда могут вкрасться при использовании дублирующихся. Кстаи, иногда для считывания не нужны очень точные значения, бывает, что пользоватля устроят данные, по состоянию «на вчера» или «с отставанием на 10 минут», что позволяет не вычислять это для каждого пользователя, а вычислять в отложенном режиме (на событии, по крону или скедьюлу), класть в отдельную таблицу (которая конечно излишняя и дублирующая) но данные там будут в нужном порядке, с нужными ключами, и без необходимости делать одинаковые вычисления сотням пользователей в момент запроса.
Супер. Про это можно отдельно написать — будет веселый пересказ Кнута и «Структур данных» :)
И чего все от базы данных так много требуют :). У меня это хранилище и только не более 20% база данных. Когда половина информации хранится в бинарном, а потом ещё сжатом виде с распределителем записывающим данные :). У меня только для каждого слова своя таблица запакованная в базу слов, отдельно база для хранения исходных страниц и т.д. и т.п. Т.е. 80% случаев это расширенный интерфейс к API файловой системы + обвязка в виде хешей даных в памяти и т.п.
Sign up to leave a comment.

Articles