Re[3]: Вертикальное партицирование - есть ли смысл?
От: Sinclair Россия https://github.com/evilguest/
Дата: 03.11.09 06:25
Оценка: 8 (1) +2
Здравствуйте, MozgC, Вы писали:
MC>И еще давайте разберем конкретный пример.
MC>Допустим есть таблица order_lines, в ней порядка 40 столбцов. Теперь потребовалось приделать комментарий к order line. Добавил поле Comment. Через год потребовалось узнать время в которое был поставлен комментарий, чтобы к примеру можно было посмотреть все проставленные комментарии за сегодня. Собираюсь добавить столбец TSComments типа TIMESTAMP.
MC>Вы бы сделали так же?
Хм. Сразу возникает вопрос: а сколько таких комментариев может быть? Пока не было "времени", комментарий существовал как бы в виде неделимой сущности.
Если нам надо через неделю что-то добавить — то просто дописываем к телу комментария и всё.
А вот введение даты сразу же вводит новое измерение. Что, если теперь я добавил комментарий сегодня, а завтра хочу добавить к нему ещё что-то? Это будет считаться завтрашним комментарием, или исправленным сегодняшним?
Так что я бы тут же начал придумывать отдельную табличку, типа
create table OrderLineComments
(
  OrderLineId int not null foreign key references OrderLines(ID),
  CommentDate  datetime not null,
  Author  varchar(max) not null,
  Comment varchar(max) not null,
  primary key (OrderLineId, CommentDate)
)


MC>Хотя возможно можно вынести Comments + TSComment (+ завтра может понадобиться указывать пользователя который проставил комментарий) в отедльную таблицу. Но действительно ли от этого будет толк. Вдруг этим я только распложу кучу таблиц и потом буду дополнительно тратить время на джоины, который к тому же будут немного замедлять запрос?

А тебе во всех запросах нужны будут comments?
Скорее всего, 90% запросов их не будут использовать вообще. Значит, там не будет join-ов, замедляющих запрос.
1% потребуют join.
Еще 9% будут наоборот — искать строки по комментариям, и они только выиграют от отдельной таблицы.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re: Вертикальное партицирование - есть ли смысл?
От: wildwind Россия  
Дата: 02.11.09 08:45
Оценка: 3 (1) +2
Здравствуйте, MozgC, Вы писали:

MC>Вот я и подумал — насколько это плохо когда такая таблица разрастается до десятков колонок?

Само по себе абсолютно нормально. Сотню не видел еще? :)

MC>Имеет ли смысл делать вертикальное партицирование?

Иногда имеет

MC>Как определить когда смысл есть, а когда нет?

1. Понять проблему (заодно убедиться в ее существовании :). Обычно это производительность.
2. Оценить эффект от этого шага. Количественно, с помощью моделирования.
3. Оценить проблемы, порождаемые этим шагом. Изменение кода, усложнение запросов, другие запросы станут наоборот тяжелее и т.д.
4. Решить, стоит ли овчинка выделки.
В общем, как обычно.
Re[5]: Вертикальное партицирование - есть ли смысл?
От: maxluzin Европа  
Дата: 04.11.09 15:19
Оценка: 2 (1) -1
Здравствуйте, MozgC, Вы писали:

MC>Поговорил тут с одним специалистом, очень хорошо на мой взгляд разбирающимся в БД.


Ну, это на Ваш взгляд (дальше конкретизирую)...

MC>Он говорит что всегда в таких случаях, когда определенные столбцы используются редко, выносит эти столбцы в отдельную таблицу.


Я тоже могу сказать, что жену пять раз в день "удовлетворяю"... Ну и Вы говорите! Кто запрещает?!

MC>Основные причины:


MC>1) Уменьшение размера базы данных. Так как в большинстве случаев используется фиксированный размер строк, поэтому если в таблице с миллионом строк указано только 10% комментариев (varchar(250)), то экономия размера базы будет — сотни мегабайт (примерно от 235 Мб до более полугигабайта в зависимости от используемой кодировки).


Выносить данные в отдельную (связанную по первичному ключу) таблицу нужно только в случае действительно реальной экономии! Это работает действительно только на сверхбольших базах. Вообще-то, база читается в ОП страницами и блоками, независимо практически от самой структуры БД... Тут надо понимать, что "движки" современных серверов БД — они над "файл-системные", т.е. в любом современном движке СУБД присутствует уровень абстракции над конкретной файловой системой. Будь то "Виндоза", или "Линух", или МВС... Тут надо ещё и "физику" смотреть... Реально, честно говоря, платформа имеет значение. Даже аппаратная конфигурация... Да даже "группы файлов", и физическое расположение дисков и уровни РАИД-а! Если база многфайловая и физически располагается на разных дисках...

MC>2) Ускорение чтения (и записи) с жесткого диска. Допустим чтение происходит блоками по 8К и размер записи — N, тогда в 1 блоке уместится 8К/N записей в случае если комментарий у нас в общей таблице и 8K/(N-250) если комментарий в отдельной таблице. С одной стороны зачастую практически вся БД может находиться в кеше, с другой стороны даже в таком случае время от времени происходит сохранение из кеша на жесткий диск, т.е. некоторая разница все равно будет.


Нет. Вся БД может находиться в кэше только в случае, если БД размером в десяток мегабайт... А так для многих современных алгоритмов кэширования БД 4-6% от физического размера БД в кэше (в ОП сервера БД) — это уже более чем достаточно, и дальнейшее увеличение размеров кеширования страниц БД в ОП — выйгрышь по экспоненте резко сокращается... Тут опять же работает то самое пресловутое Правило Паретто (20/80)...

MC>3) Ускорение выполнения некоторых запросов, иногда многократное ускорение. И речь идет не только о случае с SELECT * FROM order_lines когда комментарии не нужны в выборке.

MC>Допустим заполнен малый процент комментариев. И нужно выбрать все комментарии за сегодня. В случае когда комментарии находятся в той же таблице запрос будет такой:
MC>
SELECT ... FROM order_lines WHERE Comment IS NOT NULL AND CAST(TSComment AS DATE) = '2009-11-02'

MC>Будет перебрана куча записей, чтобы найти требуемые записи с комментариями.

Я не знаю, на что ориентирован Ваш "эксперт по БД", но ещё на первых курсах по Ораклу говорится, что выражение "IS NOT NULL" в "where" автоматически вырубает все схемы оптимизаторов запросов и идёт "тупой" и прямолинейный "Full Scan"... Ну нет в реляционной алгебре и движках такой мат.конструкции, как проверка "на наличие пустоты"! Я могу ошибаться, но насколько я знаю, даже в "движках" БД MS SQL Server и MySQL всех версий конструкции в "WHERE", типа "IS NOT NULL" надо избегать, т.к. они не реляционные! Я бы в данном случае просто внёс бы в основную таблицу два поля (колонки):

1. Однобайтовую (Fixed(1)), как признак наличия комментария (или какой-то другой однобайтовый флаг).
2. Дату последнего комментария (может быть и NULL значения по-умолчанию).

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

MC>Такая выборка будет заметно менее быстрой чем в случае когда комментарии хранятся в отдельной таблице:

MC>
SELECT ... FROM order_line_comments INNER JOIN order_lines ON (...) WHERE CAST(TSComment AS DATE) = '2009-11-02'

MC>Разница в скорости в таких запросах скорее всего будет в разы.

Вообще-то, "будем посмотреть"... CAST вообще надо избегать... Я вообще-то иногда ввожу в базы некоторые Fixed(1) "флаги" о "наличии присутствия" того или иного события (факта)... Хоть это и нарушает правила нормализации, но существенно ускоряет работу в БД! Например, дату закрытия заказа платёжкой я дополняю просто полем самого факта закрытия строки заказа (логическим или фиксированным однобайтовым "Х" или "1"). А если такое поле входит в какой-либо индекс, то уже нет надобности делать запрос только по датам в выражении "where", оптимизатор "по факту (атрибуту, флагу) отфильтрует все записи из таблицы ("закрытые заказы"), а уж потом их будет анализировать на дату (интервал или равенство)... Тут надо ещё смотреть, какую степень селективности индексы имеют! Дело в том, что многие оптимизаторы СУБД просто игнорируют построенные индексы, если у них низкая степень селективности... Короче, "физические алгоритмы оптимизаторов" могут выбрать такой план, что индексы ВООБЩЕ не будут использоваться! Это особенно для DB2 и Oracle характерно! Поверьте! Перенесение "чиста десктоповского" опыта на СУБД промышленного масштаба не работает! Там ещё и РАИД-ы надо учитывать... Да и вообще — "железо"!

MC>4) Разносим индексы по разным таблицам. Во-первых, теперь индексы будут обновляться реже: к примеру при вставке записи без комментария индексы в таблице комментариев не трогаются. Во-вторых, в некоторых СУБД будет и сокращение размеров индексов (к примеру в SQL Server индексы включают указатели на строки с null-значением индексируемого столбца, соответственно индекс по Comment в таблице order_lines будет намного больше, чем индекс по Comment в таблице order_line_comments).


Это хорошо, если так... Но обычно "NULL-поля" вообще в индекс не попадают... А это уже очень интересная ситуация... Но, опять же, всё зависит от движка... "IS NULL" многие "движки" принимают в расчёт во время запроса, а вот "NOT is null" игнорируют и делают оптимизацию плана по другим критериям — частенько просто тупо сканируют базу... Надо смотреть! О какой базе вообще речь идёт?

MC>Ну вот такие вот мысли.


Хорошие мысли. Не глупые. Только у советчика спросите обязательно: он про какую базу речь вёл? Ибо это важно!
индексы оптимизация бд where null
Re[5]: Вертикальное партицирование - есть ли смысл?
От: maxluzin Европа  
Дата: 02.11.09 10:26
Оценка: +1 :)
Здравствуйте, wildwind, Вы писали:

W>Я имею в виду ситуацию, когда как раз очевидно, что нужно денормализовать. И это один из этапов проектирования.


Я завидую тем, кому всё очевидно на этапе проектирования...

Хотя sequential scan в Oracle иногда гораздо эффективнее, чем нормализованные и заиндексированные "вусмерть" таблицы... Впрочем, оптимизаторы запросов сейчас сами весьма эффективные планы строят, если их "не тыкать мордой" в свои планы и не навязывать свои атрибуты и "подсказки"... В общем, сейчас это уже не так критично всё, если там пару-тройку десятков колонок в таблицу добавишь — не те времена уже...
Re: Вертикальное партицирование - есть ли смысл?
От: maxluzin Европа  
Дата: 02.11.09 08:33
Оценка: 3 (1)
Здравствуйте, MozgC, Вы писали:

MC>Здравствуйте,


MC>Иногда в процессе работы таблицы постепенно разрастаются очень сильно, и горизонтально и вертикально. К примеру у нас order lines содержит несколько десятков столбцов. И сейчас мне вот надо очередную колонку добавить — таймстемп установки комментария, дополнительно к уже имеющемуся комментарию.


Это нормально для развивающегося проекта...

MC>Вот я и подумал — насколько это плохо когда такая таблица разрастается до десятков колонок? Имеет ли смысл делать вертикальное партицирование? Как определить когда смысл есть, а когда нет?


Если такое безобразие возникло на этапе проектирования структуры БД — то это плохо, а если "жизнь диктует" — то это почти повсеместно...

MC>Не замучаюсь ли я потом джоины писать к тому же они будут замедлять выполнение запросов. Как лучше партицировать? На 2 таблицы (90% наиболее часто используемых колонок в одну таблицу, остальные — в другую) или по смысловым группам?

MC>Приведите конкретные примеры и результаты из вашей практики?

База данных SAP R/3, например... Это что-то с чем-то! Там те же Order Lines разбиты ещё и по модулям! Одно дело модуль продаж — SD, а другое: Финансы (FI), Контроллинг (CO) и ещё куча модулей SAP-а, которые с этими самыми "строчками Заказа" связаны чисто функционально... Вообще-то в САП-е БД в большинстве случаев поставляется ВСЯ со всеми дефинициями таблиц! Так что в системе ТЫСЯЧИ таблиц находятся пустыми без единой строчки! В других системах ERP таблицы добавляются в схему, в зависимости от докупаемых и интегрируемых модулей.

Суть не в этом! Если функционально аттрибут нужен, то он должен быть!

Тут есть такое золотое эмпирическое правило Паретто "20/80": "80% всех запросов — используют только 20% данных, оставшиеся 20% запросов к БД используют 80% данных" и т.д. и т.п. Поэтому так и надо планировать. В общем случае: Таблица статических данных (неменяющихся, атрибутов, остающихся "пожизненно" в БД) -> Таблицы, связанные со статической по атрибутам, разделённым по функционалу. Связь, естественно, по первичному ключу...

Тут ещё имеет значение, какая конкретно БД используется... Чаще всего данные читаются постранично или сегментно из БД. "Позаписно" практически ни одна современная БД данные уже не считывает. Т.е. данные страницами или сегментами загружаются в кэш БД (в ОП) и уже в нём обрабатываются "позаписно". Но тут есть ещё такой момент: поля фиксированы или с переменной длиной? Это уже хоть уже и почти не имеет значения для современных серверов БД, но лучше в таблицах данные (поля, атрибуты) с фиксированной длиной располагать ближе к "левому краю" записей, т.к. указатель в памяти в кэше (а обработка данных идёт ТОЛЬКО в кэше, после загрузки страницы/сегмента/блока данных БД в ОП) может быть сразу перемещён на нужную позицию в сегменте данных, если все поля до нужного поля фиксированной длины... Но это в общем случае и не так критично с точки зрения современных "движков БД". Гораздо важнее именно делать правильную вертикальную сегментацию таблиц, ориентируюсь именно на процент (или вероятность) запросов к этим данным... Если данные редко используются, то их лучше вынести в отдельную таблицу и связать по первичному ключу.
Re[4]: Вертикальное партицирование - есть ли смысл?
От: MozgC США http://nightcoder.livejournal.com
Дата: 02.11.09 21:50
Оценка: +1
Поговорил тут с одним специалистом, очень хорошо на мой взгляд разбирающимся в БД.

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

Основные причины:

1) Уменьшение размера базы данных. Так как в большинстве случаев используется фиксированный размер строк, поэтому если в таблице с миллионом строк указано только 10% комментариев (varchar(250)), то экономия размера базы будет — сотни мегабайт (примерно от 235 Мб до более полугигабайта в зависимости от используемой кодировки).

2) Ускорение чтения (и записи) с жесткого диска. Допустим чтение происходит блоками по 8К и размер записи — N, тогда в 1 блоке уместится 8К/N записей в случае если комментарий у нас в общей таблице и 8K/(N-250) если комментарий в отдельной таблице. С одной стороны зачастую практически вся БД может находиться в кеше, с другой стороны даже в таком случае время от времени происходит сохранение из кеша на жесткий диск, т.е. некоторая разница все равно будет.

3) Ускорение выполнения некоторых запросов, иногда многократное ускорение. И речь идет не только о случае с SELECT * FROM order_lines когда комментарии не нужны в выборке.
Допустим заполнен малый процент комментариев. И нужно выбрать все комментарии за сегодня. В случае когда комментарии находятся в той же таблице запрос будет такой:
SELECT ... FROM order_lines WHERE Comment IS NOT NULL AND CAST(TSComment AS DATE) = '2009-11-02'

Будет перебрана куча записей, чтобы найти требуемые записи с комментариями.
Такая выборка будет заметно менее быстрой чем в случае когда комментарии хранятся в отдельной таблице:
SELECT ... FROM order_line_comments INNER JOIN order_lines ON (...) WHERE CAST(TSComment AS DATE) = '2009-11-02'

Разница в скорости в таких запросах скорее всего будет в разы.

4) Разносим индексы по разным таблицам. Во-первых, теперь индексы будут обновляться реже: к примеру при вставке записи без комментария индексы в таблице комментариев не трогаются. Во-вторых, в некоторых СУБД будет и сокращение размеров индексов (к примеру в SQL Server индексы включают указатели на строки с null-значением индексируемого столбца, соответственно индекс по Comment в таблице order_lines будет намного больше, чем индекс по Comment в таблице order_line_comments).

Ну вот такие вот мысли.
Re[6]: Вертикальное партицирование - есть ли смысл?
От: _d_m_  
Дата: 25.02.10 04:48
Оценка: -1
Здравствуйте, MozgC, Вы писали:

MC>Здравствуйте, MozgC, Вы писали:


MC>Основные причины:


MC>1) Уменьшение размера базы данных. Так как в большинстве случаев используется фиксированный размер строк, поэтому если в таблице с миллионом строк указано только 10% комментариев (varchar(250)), то экономия размера базы будет — сотни мегабайт (примерно от 235 Мб до более полугигабайта в зависимости от используемой кодировки).


Ерунда. На то он и varchar, что занимает места по длине строки.
Re[8]: Вертикальное партицирование - есть ли смысл?
От: _d_m_  
Дата: 25.02.10 08:40
Оценка: :)
Здравствуйте, MozgC, Вы писали:

___>>Ерунда. На то он и varchar, что занимает места по длине строки.


MC>Это зависит от СУБД и движка. Например в MySql если у MyISAM таблицы Row Format = FIXED, то все строки таблицы будут фиксированного размера, т.е. под строку таблицы резервируется максимальное место на диске.


MySQL недоСУБД.
Вертикальное партицирование - есть ли смысл?
От: MozgC США http://nightcoder.livejournal.com
Дата: 31.10.09 21:41
Оценка:
Здравствуйте,

Иногда в процессе работы таблицы постепенно разрастаются очень сильно, и горизонтально и вертикально. К примеру у нас order lines содержит несколько десятков столбцов. И сейчас мне вот надо очередную колонку добавить — таймстемп установки комментария, дополнительно к уже имеющемуся комментарию.
Вот я и подумал — насколько это плохо когда такая таблица разрастается до десятков колонок? Имеет ли смысл делать вертикальное партицирование? Как определить когда смысл есть, а когда нет?
Не замучаюсь ли я потом джоины писать к тому же они будут замедлять выполнение запросов. Как лучше партицировать? На 2 таблицы (90% наиболее часто используемых колонок в одну таблицу, остальные — в другую) или по смысловым группам?
Приведите конкретные примеры и результаты из вашей практики?

Заранее спасибо.
Re: Вертикальное партицирование - есть ли смысл?
От: MasterZiv СССР  
Дата: 01.11.09 13:05
Оценка:
MozgC пишет:

Достаточно недавно обсуждали тему про "широкие" таблицы, найдите, посмотрите.
Это то же самое.
Posted via RSDN NNTP Server 2.1 beta
Re[2]: Вертикальное партицирование - есть ли смысл?
От: MozgC США http://nightcoder.livejournal.com
Дата: 01.11.09 13:49
Оценка:
Здравствуйте, MasterZiv, Вы писали:

MZ>Достаточно недавно обсуждали тему про "широкие" таблицы, найдите, посмотрите.

MZ>Это то же самое.

Честно искал, также просмотрел все темы за последние 1.5 месяца, не нашел.
Re[3]: Вертикальное партицирование - есть ли смысл?
От: ZAMUNDA Земля для жалоб и предложений
Дата: 02.11.09 07:40
Оценка:
Здравствуйте, MozgC, Вы писали:

MC>Честно искал, также просмотрел все темы за последние 1.5 месяца, не нашел.

http://img.meta.ua/rsdnsearch/?q=%22%F8%E8%F0%EE%EA%E8%E5%22%2B%F2%E0%E1%EB%E8%F6%FB&amp;mode=rank&amp;group=N&amp;group=6
Наука изощряет ум; ученье вострит память.
(c) Козьма Прутков
Re[2]: Вертикальное партицирование - есть ли смысл?
От: wildwind Россия  
Дата: 02.11.09 08:46
Оценка:
Здравствуйте, maxluzin, Вы писали:

M>Если такое безобразие возникло на этапе проектирования структуры БД — то это плохо


Почему?
Re[3]: Вертикальное партицирование - есть ли смысл?
От: maxluzin Европа  
Дата: 02.11.09 09:15
Оценка:
Здравствуйте, wildwind, Вы писали:

W>Здравствуйте, maxluzin, Вы писали:


M>>Если такое безобразие возникло на этапе проектирования структуры БД — то это плохо


W>Почему?


Э-э-э... Это "первый звоночек", что что-то с нормализацией БД идёт не так... Но, согласен, не надо бить тревогу, пока процесс не становится НЕконтролируемым... В сущности, для современных БД даже десятки (и даже сотни!) колонок в одной таблице — это уже не является основой для "потери сна" и "навязчивых кошмаров". Тут многое надо оценивать и с точки зрения структуры запросов к БД и с точки зрения алгоритмов самого приложения... Короче, проектирование схемы БД — это в некоторых случаях искусство! Иногда надо "предчувствовать", как оно всё через полгода-год-два повернётся... На этапе проектирования БД это иногда совсем неочевидно. А значит, если не очевидно, есть золотое правило: "если не знаешь последствий или будущего — не выдумывай велосипед, а просто следуй консервативным правилам!"
Re[4]: Вертикальное партицирование - есть ли смысл?
От: wildwind Россия  
Дата: 02.11.09 09:48
Оценка:
Здравствуйте, maxluzin, Вы писали:

M>Короче, проектирование схемы БД — это в некоторых случаях искусство! Иногда надо "предчувствовать", как оно всё через полгода-год-два повернётся... На этапе проектирования БД это иногда совсем неочевидно.


Я имею в виду ситуацию, когда как раз очевидно, что нужно денормализовать. И это один из этапов проектирования.
Re[2]: Вертикальное партицирование - есть ли смысл?
От: MozgC США http://nightcoder.livejournal.com
Дата: 02.11.09 13:29
Оценка:
В общем вот как я понял ситуацию:
1) Порядка 40 столбцов в таблице это нормально (понятно что с нормализацией все нормально, т.е. все столбцы реально к примеру описывают order line, т.е. в тему) и переживать не стоит
2) Можно вынести в отдельную таблицу только если этот столбец используется очень редко (как мне кажется заморачиваться с разделением на таблицы в таком случае нужно только если столбец используется очень редко, к примеру в 1% запросов)

Правильно я понимаю?

Следующие вопросы к тем кто на практике занимается вертикальным партицированием:
1) Замеряли ли вы реальную разницу в скорости работы? Какие результаты?
2) Какие минусы вы встретили после этого

И еще давайте разберем конкретный пример.
Допустим есть таблица order_lines, в ней порядка 40 столбцов. Теперь потребовалось приделать комментарий к order line. Добавил поле Comment. Через год потребовалось узнать время в которое был поставлен комментарий, чтобы к примеру можно было посмотреть все проставленные комментарии за сегодня. Собираюсь добавить столбец TSComments типа TIMESTAMP.
Вы бы сделали так же?
Хотя возможно можно вынести Comments + TSComment (+ завтра может понадобиться указывать пользователя который проставил комментарий) в отедльную таблицу. Но действительно ли от этого будет толк. Вдруг этим я только распложу кучу таблиц и потом буду дополнительно тратить время на джоины, который к тому же будут немного замедлять запрос?

Вот так вот и терзаюсь в незнании как лучше и правильнее
Re[4]: Вертикальное партицирование - есть ли смысл?
От: MasterZiv СССР  
Дата: 02.11.09 15:34
Оценка:
ZAMUNDA пишет:

> MC>Честно искал, также просмотрел все темы за последние 1.5 месяца, не


Я найду ветку, что я имел в виду. Возможно, я перепутал, и она была на sql.ru.
Posted via RSDN NNTP Server 2.1 beta
Re[3]: Вертикальное партицирование - есть ли смысл?
От: maxluzin Европа  
Дата: 02.11.09 17:31
Оценка:
Здравствуйте, MozgC, Вы писали:

MC>В общем вот как я понял ситуацию:

MC>1) Порядка 40 столбцов в таблице это нормально (понятно что с нормализацией все нормально, т.е. все столбцы реально к примеру описывают order line, т.е. в тему) и переживать не стоит
MC>2) Можно вынести в отдельную таблицу только если этот столбец используется очень редко (как мне кажется заморачиваться с разделением на таблицы в таком случае нужно только если столбец используется очень редко, к примеру в 1% запросов)

MC>Правильно я понимаю?


Правильно понимаешь! Вообще, не бойся нарушать запреты! Но! Если в чём-то сомневаешься, действуй "по-классике"... Стандартные схемы действуют всегда в общем случае!

MC>Следующие вопросы к тем кто на практике занимается вертикальным партицированием:

MC>1) Замеряли ли вы реальную разницу в скорости работы? Какие результаты?
MC>2) Какие минусы вы встретили после этого

1. Не замерял. Было пару случаев, когда просто знал, что это улучшит структуру таблицы и скорость запросов.
2. Ну какие какие... Дополнительные затраты времени на перекройку таблиц и ещё на администрирование...

MC>И еще давайте разберем конкретный пример.

MC>Допустим есть таблица order_lines, в ней порядка 40 столбцов. Теперь потребовалось приделать комментарий к order line. Добавил поле Comment. Через год потребовалось узнать время в которое был поставлен комментарий, чтобы к примеру можно было посмотреть все проставленные комментарии за сегодня. Собираюсь добавить столбец TSComments типа TIMESTAMP.
MC>Вы бы сделали так же?

Я бы сделал... Но сначала бы BLOB-ы или текстовые длинные поля вынес бы вообще сразу в отдельную таблицу! Даже в отдельный tablespace (Oracle), а если вообще всё так печально, то и в отдельный filegroup, куда-нибудь "в отстой" с другой схемой RAID-а... Но поять же! Всё зависит от объёма данных и от типа и видов запросов к БД! Может, в твоём случае, это вообще не существенно! Перекроить-то схему — это не долго вообще-то! Да даже запросы не так уж долго... Ну, разумеется, если был создан уровень "представлений" (view) или "stored procedures"...

MC>Хотя возможно можно вынести Comments + TSComment (+ завтра может понадобиться указывать пользователя который проставил комментарий) в отедльную таблицу. Но действительно ли от этого будет толк. Вдруг этим я только распложу кучу таблиц и потом буду дополнительно тратить время на джоины, который к тому же будут немного замедлять запрос?


Будет, будет! Все комменты, БЛОБы и прочие нерегулярные объекты выноси из главной таблицы сразу! Всё равно в большинстве реализаций они вообще никак не участвуют в SQL-запросах! Ну, кроме, полнотекстового поиска... А это есть в запросах? Выноси! Даже не задумывайся! И куда подальше от реального дискового пространства, где хранятся статические и оперативные таблицы! Ну, извини, это ещё и от конкретной базы зависит! Вот я знаяю, например, где там есть "тонкие места" в Оракле, Майкрософте и в МайСикуеле... Ой! Так сразу и не ответишь! Есть там заморочки СВОИ! Надо смотреть... Так сразу и не ответишь...

MC>Вот так вот и терзаюсь в незнании как лучше и правильнее


Абстаргируйся от самих таблиц! Делай больше запросов через "представления"! Вообще-то, я уже давно пользую такую модель (паттерн?), чтоб толко через "представления" (view) к базам обращаться... Поверь! Самое большие потери производительности не превышали 2%... И в алгоритме самой задачи больше "собак рылось"! Оптимизаторы современных БД достатчоно хорошо "представления" акцептируют... Но опять же! О какой базе мы говорим? У каждой есть свои тонкости и заморочки... Так просто универсально совет и не дашь! Ну, есть правила общие для всех реляционных БД... Есть теория... Но нужно СМОТРЕТЬ!

Честно говоря, нет никакой гарантии, что "вертикальное партицирование" как-то улучшит или ухудшит твои приложения, работающие с БД... Смотри сам! Может дело и не в структуре БД? Может дело в самих "аппликациях"?
Re[3]: Вертикальное партицирование - есть ли смысл?
От: maxluzin Европа  
Дата: 02.11.09 17:44
Оценка:
Здравствуйте, MozgC, Вы писали:

MC>Вдруг этим я только распложу кучу таблиц и потом буду дополнительно тратить время на джоины, который к тому же будут немного замедлять запрос?


Забыл добавить... Посмотри через профайлер своей базы на сложные запросы... Там пресловутые "джоины" могут рядом и вокруг! Левые, правые... Какая разница! SQL — это всего лишь язык доступа к БД! Но это совсем не значит, что на уровне "движка" БД все твои запросы будут выполнятся именно так, как их ты синтаксически описал! Даже "хинты" могут не работать, если в параметрах старта сервера не будет соответствующих указаний!

Так что не бойся "джоинов"! они могут бытьповсеместно просто по матмодели движка БД! Даже если ты этого не хочешь!
Re[3]: Вертикальное партицирование - есть ли смысл?
От: wildwind Россия  
Дата: 02.11.09 17:58
Оценка:
Здравствуйте, MozgC, Вы писали:

MC>И еще давайте разберем конкретный пример.

MC>...
MC>Собираюсь добавить столбец TSComments типа TIMESTAMP.
MC>Вы бы сделали так же?

Ну давай, что по первому пункту (моему)? Какую проблему может представлять добавление TSComments в эту же таблицу?
Re[4]: Вертикальное партицирование - есть ли смысл?
От: MozgC США http://nightcoder.livejournal.com
Дата: 02.11.09 18:12
Оценка:
Здравствуйте, wildwind, Вы писали:

W>Ну давай, что по первому пункту (моему)? Какую проблему может представлять добавление TSComments в эту же таблицу?


Во-первых, не нарушает ли TSComment вторую-третью нормальную форму? Потому что можно сказать что TSComment описывает не позицию заказа, а комментарий, т.е. неключевой атрибут сущности. По крайней мере мне кажется что такой взгляд имеет право на жизнь.
Во-вторых, это может повлять на производительность запросов, только я не знаю насколько, особенно в сумме, когда из-за таких столбцов в течение нескольких лет таблица расползается до сотни столбцов.
Хотя даже замерить это будет сложновато, потому что скорее всего вся таблица будет в кеше СУБД (если сервер неслабый) и тогда навряд ли будет сколь-нибудь заметное изменение производительности. Это все имхо.
Re[4]: Вертикальное партицирование - есть ли смысл?
От: maxluzin Европа  
Дата: 04.11.09 15:49
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, MozgC, Вы писали:

MC>>И еще давайте разберем конкретный пример.
MC>>Допустим есть таблица order_lines, в ней порядка 40 столбцов. Теперь потребовалось приделать комментарий к order line. Добавил поле Comment. Через год потребовалось узнать время в которое был поставлен комментарий, чтобы к примеру можно было посмотреть все проставленные комментарии за сегодня. Собираюсь добавить столбец TSComments типа TIMESTAMP.
MC>>Вы бы сделали так же?
S>Хм. Сразу возникает вопрос: а сколько таких комментариев может быть? Пока не было "времени", комментарий существовал как бы в виде неделимой сущности.

Совершенно верно! Тут появляется однозначно ещё одна сущность: "мультикомментарность!"

S>Если нам надо через неделю что-то добавить — то просто дописываем к телу комментария и всё.

S>А вот введение даты сразу же вводит новое измерение. Что, если теперь я добавил комментарий сегодня, а завтра хочу добавить к нему ещё что-то? Это будет считаться завтрашним комментарием, или исправленным сегодняшним?
S>Так что я бы тут же начал придумывать отдельную табличку, типа
S>
S>create table OrderLineComments
S>(
S>  OrderLineId int not null foreign key references OrderLines(ID),
S>  CommentDate  datetime not null,
S>  Author  varchar(max) not null,
S>  Comment varchar(max) not null,
S>  primary key (OrderLineId, CommentDate)
S>)
S>


Вот видишь, как постановка задачи или новые требования могут существенно изменить схему самой БД! Вот это правильно! Такой подход мне нравится!

MC>>Хотя возможно можно вынести Comments + TSComment (+ завтра может понадобиться указывать пользователя который проставил комментарий) в отедльную таблицу. Но действительно ли от этого будет толк. Вдруг этим я только распложу кучу таблиц и потом буду дополнительно тратить время на джоины, который к тому же будут немного замедлять запрос?

S>А тебе во всех запросах нужны будут comments?
S>Скорее всего, 90% запросов их не будут использовать вообще. Значит, там не будет join-ов, замедляющих запрос.
S>1% потребуют join.
S>Еще 9% будут наоборот — искать строки по комментариям, и они только выиграют от отдельной таблицы.

Не только от отдельной таблицы, а скорее всего, придётся вынести её в отдельный файл, а потом в отдельный "файл-гроуп", а потом вообще на отдельный диск или вообще — в отдельный РАИД-массив, если ситуация вообще "печальная" или "массовая", типа "Одноклассников.ру" или какой-то ещё простой, но массовой схемы БД...
Re[5]: Вертикальное партицирование - есть ли смысл?
От: MozgC США http://nightcoder.livejournal.com
Дата: 20.02.10 19:50
Оценка:
Здравствуйте, MozgC, Вы писали:

Основные причины:

1) Уменьшение размера базы данных. Так как в большинстве случаев используется фиксированный размер строк, поэтому если в таблице с миллионом строк указано только 10% комментариев (varchar(250)), то экономия размера базы будет — сотни мегабайт (примерно от 235 Мб до более полугигабайта в зависимости от используемой кодировки).

2) Ускорение чтения (и записи) с жесткого диска. Допустим чтение происходит блоками по 8К и размер записи — N, тогда в 1 блоке уместится 8К/N записей в случае если комментарий у нас в общей таблице и 8K/(N-250) если комментарий в отдельной таблице. С одной стороны зачастую практически вся БД может находиться в кеше, с другой стороны даже в таком случае время от времени происходит сохранение из кеша на жесткий диск, т.е. некоторая разница все равно будет.

3) Ускорение выполнения некоторых запросов, иногда многократное ускорение. И речь идет не только о случае с SELECT * FROM order_lines когда комментарии не нужны в выборке.
Допустим заполнен малый процент комментариев. И нужно выбрать все комментарии за сегодня. В случае когда комментарии находятся в той же таблице запрос будет такой:

SELECT ... FROM order_lines WHERE Comment IS NOT NULL AND CAST(TSComment AS DATE) = '2009-11-02'

Будет перебрана куча записей, чтобы найти требуемые записи с комментариями.
Такая выборка будет заметно менее быстрой чем в случае когда комментарии хранятся в отдельной таблице:
SELECT ... FROM order_line_comments INNER JOIN order_lines ON (...) WHERE CAST(TSComment AS DATE) = '2009-11-02'

Разница в скорости в таких запросах скорее всего будет в разы.

4) Разносим индексы по разным таблицам. Во-первых, теперь индексы будут обновляться реже: к примеру при вставке записи без комментария индексы в таблице комментариев не трогаются. Во-вторых, в некоторых СУБД будет и сокращение размеров индексов (к примеру в SQL Server индексы включают указатели на строки с null-значением индексируемого столбца, соответственно индекс по Comment в таблице order_lines будет намного больше, чем индекс по Comment в таблице order_line_comments).


5) Повышение конкурентности — т.е. строки исходной таблицы или вся таблица (если произойдет lock escalation или если определенный движок СУБД не поддерживает блокировку на уровне строк) не будут теперь блокироваться при изменении новых столбцов, т.к. эти столбцы вынесены в отдельную таблицу.
Re[7]: Вертикальное партицирование - есть ли смысл?
От: MozgC США http://nightcoder.livejournal.com
Дата: 25.02.10 07:50
Оценка:
Здравствуйте, _d_m_, Вы писали:

MC>>1) Уменьшение размера базы данных. Так как в большинстве случаев используется фиксированный размер строк, поэтому если в таблице с миллионом строк указано только 10% комментариев (varchar(250)), то экономия размера базы будет — сотни мегабайт (примерно от 235 Мб до более полугигабайта в зависимости от используемой кодировки).


___>Ерунда. На то он и varchar, что занимает места по длине строки.


Это зависит от СУБД и движка. Например в MySql если у MyISAM таблицы Row Format = FIXED, то все строки таблицы будут фиксированного размера, т.е. под строку таблицы резервируется максимальное место на диске.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.