Я сталкиваюсь со следующей проблемой. У меня очень большой стол. Этот стол является наследием людей, которые ранее работали над проектом. Таблица находится в MS SQL Server.
Таблица имеет следующие свойства:
- он имеет около 300 столбцов. Все они имеют «текстовый» тип, но некоторые из них в конечном итоге должны представлять другие типы (например, целое число или дату и время). Поэтому перед их использованием необходимо преобразовать эти текстовые значения в соответствующие типы.
- таблица имеет более 100 миллионов строк. Место для таблицы скоро достигнет 1 терабайта
- в таблице нет индексов
- таблица не имеет каких-либо реализованных механизмов секционирования.
Как вы можете догадаться, к этой таблице невозможно выполнить какой-либо разумный запрос. Сейчас в таблицу только вставляют новые записи, но ею никто не пользуется. Поэтому мне нужно перестроить его. Я планирую создать новую структуру и заполнить новую структуру данными из старой таблицы. Очевидно, я буду реализовывать разделение, но это не единственное, что нужно сделать.
Одной из наиболее важных особенностей таблицы является то, что те поля, которые являются чисто текстовыми (т. е. их не нужно преобразовывать в другой тип), обычно имеют часто повторяющиеся значения. Таким образом, фактическое разнообразие значений в данном столбце находится в диапазоне от 5 до 30 различных значений. Это наводит на мысль сделать нормализацию: для каждого такого текстового столбца я создам дополнительную таблицу со списком всех различных значений, которые могут появиться в этом столбце, затем я создам первичный ключ (tinyint) в этой дополнительной таблице и затем будет использовать соответствующий внешний ключ в исходной таблице вместо сохранения этих текстовых значений в исходной таблице. Затем я добавлю индекс к этому столбцу внешнего ключа. Количество столбцов, которые будут обработаны таким образом, составляет около 100.
Возникают следующие вопросы:
- действительно ли эта нормализация увеличит скорость запросов, налагающих условия на некоторые из этих 100 полей? Если мы забудем о размере, необходимом для хранения этих столбцов, будет ли какое-либо увеличение производительности из-за замены исходных текстовых столбцов столбцами tinyint? Если я не буду выполнять нормализацию и просто поставлю индекс для этих исходных текстовых столбцов, будет ли производительность такой же, как для индекса для запланированного столбца tinyint?
- Если я выполню описанную нормализацию, то для создания представления, показывающего текстовые значения, потребуется соединить мою основную таблицу с примерно 100 дополнительными таблицами. Положительным моментом является то, что эти объединения я буду делать для пар "первичный ключ"="внешний ключ". Но все же достаточно большое количество таблиц должно быть объединено. Вот вопрос: не будет ли производительность запросов к этому представлению по сравнению с производительностью запросов к исходной ненормализованной таблице хуже? Действительно ли SQL Server Optimizer сможет оптимизировать запрос таким образом, чтобы воспользоваться преимуществами нормализации?
Извините за такой длинный текст.
Спасибо за каждый комментарий!
PS Я создал связанный вопрос о присоединении к 100 таблицам; Объединение 100 таблиц