Порядок столбцов оказал большое влияние на производительность некоторых настраиваемых мной баз данных, включая Sql Server, Oracle и MySQL. В этом посте есть хорошие практические правила :
- Сначала столбцы первичного ключа
- Следующие столбцы внешнего ключа.
- Столбцы, которые часто ищут, далее
- Часто обновляемые столбцы позже
- Обнуляемые столбцы идут последними.
- Наименее используемые столбцы, допускающие значение NULL, после более часто используемых столбцов, допускающих значение NULL
Примером разницы в производительности является поиск по индексу. Механизм базы данных находит строку на основе некоторых условий в индексе и возвращает адрес строки. Теперь предположим, что вы ищете SomeValue, и он находится в этой таблице:
SomeId int,
SomeString varchar(100),
SomeValue int
Движок должен угадать, где начинается SomeValue, потому что SomeString имеет неизвестную длину. Однако, если вы измените порядок на:
SomeId int,
SomeValue int,
SomeString varchar(100)
Теперь движок знает, что SomeValue можно найти через 4 байта после начала строки. Таким образом, порядок столбцов может иметь значительное влияние на производительность.
РЕДАКТИРОВАТЬ: Sql Server 2005 хранит поля фиксированной длины в начале строки. И каждая строка имеет ссылку на начало varchar. Это полностью сводит на нет указанный выше эффект. Таким образом, для недавних баз данных порядок столбцов больше не влияет.
Обновить:
В
MySQL
, может быть причина для этого.Поскольку переменные типы данных (например
VARCHAR
) хранятся с переменной длиной вInnoDB
, движок базы данных должен пройти все предыдущие столбцы в каждой строке, чтобы узнать смещение данного столбца.Воздействие может быть как 17% для
20
столбцов.См. Эту запись в моем блоге для более подробной информации:
В
Oracle
конечныеNULL
столбцы не занимают места, поэтому вы всегда должны помещать их в конец таблицы.Также в
Oracle
и вSQL Server
случае большого рядаROW CHAINING
может произойти.ROW CHANING
разбивает строку, которая не помещается в один блок, и распределяет ее на несколько блоков, связанных связным списком.Чтение завершающих столбцов, которые не помещаются в первый блок, потребует обхода связанного списка, что приведет к дополнительной
I/O
операции.См. Эту страницу для иллюстрации
ROW CHAINING
вOracle
:Вот почему вы должны помещать столбцы, которые вы часто используете, в начало таблицы, а столбцы, которые вы не используете часто, или столбцы, которые обычно используются
NULL
, в конец таблицы.Важная заметка:
Если вам понравился этот ответ и вы хотите проголосовать за него, проголосуйте также за
@Andomar
ответ .Он ответил то же самое, но, похоже, получил отрицательное голосование без всякой причины.
источник
Во время обучения Oracle на предыдущей работе наш администратор баз данных предположил, что размещение всех столбцов, не допускающих значения NULL, перед столбцами, допускающими значение NULL, было выгодным ... хотя, ЧБХ, я не помню деталей, почему. Или, может быть, в конце должны быть отправлены только те, которые, вероятно, будут обновлены? (Возможно, откладывает необходимость перемещать строку, если она расширяется)
В общем, никакой разницы не должно быть. Как вы говорите, запросы всегда должны указывать сами столбцы, а не полагаться на порядок из "select *". Я не знаю ни одной БД, которая позволяет их изменять ... ну, я не знал, что MySQL разрешает это, пока вы не упомянули об этом.
источник
Некоторые плохо написанные приложения могут зависеть от порядка / индекса столбца вместо имени столбца. Не должно быть, но это случается. Изменение порядка столбцов приведет к поломке таких приложений.
источник
Читаемость вывода, когда вам нужно набрать:
select * from <table>
в вашем программном обеспечении для управления базами данных?
Это очень надуманная причина, но сейчас я не могу думать ни о чем другом.
источник
Нет, порядок столбцов в таблице базы данных SQL совершенно не имеет значения - за исключением целей отображения / печати. Нет смысла переупорядочивать столбцы - большинство систем даже не предоставляют способ сделать это (кроме удаления старой таблицы и воссоздания ее с новым порядком столбцов).
Марк
EDIT: из записи в Википедии о реляционной базе данных, вот соответствующая часть, которая для меня ясно показывает, что порядок столбцов никогда не должен вызывать беспокойства:
Отношение определяется как набор из n кортежей. И в математике, и в модели реляционной базы данных набор представляет собой неупорядоченный набор элементов, хотя некоторые СУБД устанавливают порядок для своих данных. В математике кортеж имеет порядок и допускает дублирование. Первоначально EF Codd определял кортежи, используя это математическое определение. Позже Э. Ф. Кодд пришел к выводу, что использование имен атрибутов вместо упорядочивания было бы намного удобнее (в целом) в компьютерном языке, основанном на отношениях. Это понимание все еще используется сегодня.
источник
Единственная причина, о которой я могу думать, - это отладка и пожаротушение. У нас есть таблица, столбец «name» которой занимает 10-е место в списке. Больно, когда вы быстро выбираете * из таблицы, где идентификатор находится в (1,2,3), а затем вам нужно прокручивать, чтобы посмотреть на имена.
Но это все.
источник
Как это часто бывает, самым большим фактором является следующий человек, который должен работать с системой. Я стараюсь иметь сначала столбцы первичного ключа, затем столбцы внешнего ключа, а затем остальные столбцы в порядке убывания важности / значимости для системы.
источник
Если вы собираетесь часто использовать UNION, сопоставление столбцов будет проще, если у вас есть соглашение об их порядке.
источник
Как уже отмечалось, существует множество потенциальных проблем с производительностью. Однажды я работал с базой данных, где размещение очень больших столбцов в конце улучшало производительность, если вы не ссылались на эти столбцы в своем запросе. Очевидно, если запись занимала несколько дисковых блоков, механизм базы данных мог бы прекратить чтение блоков, как только получит все нужные столбцы.
Конечно, любые последствия для производительности сильно зависят не только от производителя, которого вы используете, но и, возможно, от версии. Несколько месяцев назад я заметил, что наши Postgres не могут использовать индекс для сравнения «нравится». То есть, если вы написали «somecolumn like 'M%'», было недостаточно умен, чтобы перейти к M и выйти, когда он нашел первый N. Я планировал изменить кучу запросов, чтобы использовать «между». Потом у нас появилась новая версия Postgres, и она грамотно справилась с подобными вещами. Рад, что мне так и не удалось изменить запросы. Очевидно, здесь это не имеет прямого отношения, но я хочу сказать, что все, что вы делаете из соображений эффективности, может устареть в следующей версии.
Порядок столбцов почти всегда очень важен для меня, потому что я обычно пишу общий код, который считывает схему базы данных для создания экранов. Например, мои экраны «редактировать запись» почти всегда создаются путем чтения схемы для получения списка полей и последующего их отображения по порядку. Если бы я изменил порядок столбцов, моя программа по-прежнему работала бы, но отображение могло быть странным для пользователя. Например, вы ожидаете увидеть имя / адрес / город / штат / почтовый индекс, а не город / адрес / почтовый индекс / имя / штат. Конечно, я мог бы указать порядок отображения столбцов в коде, или контрольном файле, или чем-то еще, но тогда каждый раз, когда мы добавляли или удаляли столбец, нам приходилось не забывать обновлять контрольный файл. Я люблю что-то сказать один раз. Кроме того, когда экран редактирования построен исключительно на основе схемы, добавление новой таблицы может означать написание нулевых строк кода для создания экрана редактирования для нее, что неплохо. (Ну, ладно, на практике мне обычно приходится добавлять элемент в меню для вызова общей программы редактирования, и я обычно отказался от универсального «выбрать запись для обновления», потому что существует слишком много исключений, чтобы сделать это практичным .)
источник
Помимо очевидной настройки производительности, я просто столкнулся с угловым случаем, когда изменение порядка столбцов приводило к сбою (ранее работавшего) сценария sql.
Из документации «столбцы TIMESTAMP и DATETIME не имеют автоматических свойств, если они не указаны явно, за этим исключением: по умолчанию первый столбец TIMESTAMP имеет как DEFAULT CURRENT_TIMESTAMP, так и ON UPDATE CURRENT_TIMESTAMP, если ни один из них не указан явно» https: //dev.mysql .com / doc / refman / 5.6 / ru / timestamp-initialization.html
Итак, команда
ALTER TABLE table_name MODIFY field_name timestamp(6) NOT NULL;
будет работать, если это поле является первой меткой времени (или даты и времени) в таблице, но не иначе.Очевидно, вы можете исправить эту команду alter, включив в нее значение по умолчанию, но тот факт, что работавший запрос перестал работать из-за переупорядочения столбцов, у меня разболелась голова.
источник
Единственный раз, когда вам нужно беспокоиться о порядке столбцов, - это если ваше программное обеспечение специально полагается на этот порядок. Обычно это происходит из-за того, что разработчик поленился и сделал,
select *
а затем сослался на столбцы по индексу, а не по имени в их результате.источник
В общем, что происходит в SQL Server, когда вы меняете порядок столбцов с помощью Management Studio, так это то, что он создает временную таблицу с новой структурой, перемещает данные в эту структуру из старой таблицы, удаляет старую таблицу и переименовывает новую. Как вы могли догадаться, это очень плохой выбор с точки зрения производительности, если у вас большая таблица. Я не знаю, делает ли мой SQL то же самое, но это одна из причин, по которой многие из нас избегают переупорядочивания столбцов. Поскольку select * никогда не следует использовать в производственной системе, добавление столбцов в конце не является проблемой для хорошо спроектированной системы. Порядок столбцов в таблице не должен изменяться.
источник
В 2002 году Билл Торстейнсон разместил на форумах Hewlett Packard свои предложения по оптимизации запросов MySQL путем изменения порядка столбцов. С тех пор его пост буквально копировали и расклеивали в Интернете не менее сотни раз, часто без цитирования. Процитировать его точно ...
Источник: форумы HP.
Но этот пост был сделан еще в 2002 году! Этот совет был для MySQL версии 3.23, более чем за шесть лет до выпуска MySQL 5.1. И никаких ссылок или цитат. Итак, был ли Билл прав? И как именно на этом уровне работает механизм хранения?
Процитируем Мартина Зана, сертифицированного специалиста Oracle , из статьи о секретах цепочки строк и миграции Oracle ...
Остальную часть статьи неплохо прочитать! Но я цитирую здесь только ту часть, которая имеет прямое отношение к нашему вопросу.
Спустя более 18 лет я должен сказать это: спасибо, Билл!
источник