![]() |
+7 (495) 229-0436 | ![]() |
shopadmin@itshop.ru | 119334, г. Москва, ул. Бардина, д. 4, корп. 3 | ![]() |
![]() |
![]() |
|
|
Lightweight Tables или практические советы при проектировании БД…27.02.2014 15:18
AlanDenton
В данном топике хотелось бы поговорить о повышении производительности при работе с таблицами. Тема не нова, но становится особенно актуальной, когда в базе наблюдается постоянный рост данных - таблицы становятся большими, а поиск и выборка по ним - медленной. Как правило, это происходит из-за плохо спроектированной схемы - изначально не рассчитанной на оперирование большими объемами данных. Чтобы рост данных в таблицах не приводил к падению производительности при работе с ними, рекомендуется взять на вооружение несколько правил при проектировании схемы. Все данные, которыми оперирует SQL Server, хранятся на, так называемых, страницах, которые имеют фиксированный размер в 8 Кб. При записи и чтении сервер оперирует именно страницами, а не отдельными строками. Поэтому, чем более компактные типы данных используются в таблице, тем меньше страниц требуется для их хранения. Меньшее число страниц - меньшее количество дисковых операций. Кроме очевидного снижения нагрузки на дисковую подсистему - в данном случае есть еще одно преимущество - при чтении с диска, любая страница вначале помещается в специальную область памяти ( Buffer Pool ), а потом уже используется по прямому назначению - для считывания или изменения данных. При использовании компактных типов данных, в Buffer Pool можно поместить больше данных на том же количестве страниц - за счет этого мы не тратим впустую оперативную память и сокращаем количество логических операций. Теперь рассмотрим небольшой пример - таблицу, в которой хранится информация о рабочих днях каждого сотрудника.
Например, очень сомнительно что сотрудников на предприятии насколько много (2^63-1), что для покрытия такой ситуации был выбран тип данных BIGINT . Уберем избыточность и посмотрим, будет ли запрос из такой таблицы более быстрым?
Весьма логично, что чем меньший объем данных требуется прочитать - тем быстрее будет выполняться сам запрос: (3492294 row(s) affected) SQL Server Execution Times: (3492294 row(s) affected) SQL Server Execution Times: Как Вы видите, использование менее избыточных типов данных зачастую положительно сказывается на производительности запросов и позволяет существенно снизить размер проблемных таблиц. К слову, узнать размер таблицы можно посредством следующего запроса:
Собственно, недавно я анализировал базу данных одного бесплатного веб-сервиса для форматирования T-SQL кода. Серверная часть там очень простая и состояла из одной единственной таблицы:
С ростом популярности сервиса, количество строк в таблице увеличилось, а обработка профилей форматирования занимала все большее количество времени. Причина заключалась в архитектуре сервиса - при каждой вставке в таблицу сохранялся полный набор настроек. Настройки имели следующую XML структуру:
Исправить ситуацию оказалось просто - все уникальные профили были вынесены в отдельную таблицу, где для каждого набора опций был получен хеш. Начиная с SQL Server 2008 для этого можно использовать функцию sys.fn_repl_hash_binary . В результате схема была нормализирована:
(3090 row(s) affected) SQL Server Execution Times: (3090 row(s) affected) SQL Server Execution Times: Но цель в данном случае преследовалась другая - ускорить аналитику. И если раньше приходилось писать очень мудреный запрос для получения списка самых популярных профилей форматирования:
(10 row(s) affected) SQL Server Execution Times: (10 row(s) affected) SQL Server Execution Times: Приятным дополнением также стало и снижение размера база данных на диске:
Третье. Осторожно выбирайте столбцы, входящие в индексы. Индексы позволяют существенно ускорить выборку из таблицы. Также как и данные из таблиц, индексы хранятся на страницах. Соотвественно. чем меньше страниц требуется для хранения индекса - тем быстрее по нему можно провести поиск. Очень важно правильно выбрать поля, которые будут входить в кластерный индекс. Поскольку все столбцы кластерного индекса автоматически входят в каждый некластерный - за счет этого может существенно увеличиваться размер базы данных. Четвертое. Используйте промежуточные и консолидированные таблицы. Здесь все достаточно просто - зачем каждый раз делать сложный запрос из большой таблицы, если есть возможность сделать простой запрос из маленькой. Например, в наличии есть запрос по консолидации данных:
(185916 row(s) affected) SQL Server Execution Times: (185916 row(s) affected) SQL Server Execution Times: Пятое. В каждом правиле есть свои исключения. Я показал пару примеров, когда изменение типов данных на менее избытоные позволяет сократить время выполнения запроса. Но это бывает не всегда. Например, у типа данных BIT есть одна особенность - SQL Server оптимизирует хранение группы столбцов этакого типа на диске. Например, если в таблице имеется 8 или меньше столбцов типа BIT , они хранятся на странице как 1 байт, если до 16 столбцов типа BIT , они хранятся как 2 байта и т.д. Хорошая новость - таблица будет занимать существенно меньше места и сократит количество дисковых операций. Плохая новость - при выборке данных этого типа будет происходить неявное декодирование, которое очень требовательно к ресурсам процессора. Покажу это на примере. Есть три идентичные таблицы, которые содержат информацию о календарном графике сотрудников (31 + 2 PK столбца). Все они отличаются только типом данных для консолидированных значений (1 - вышел на работу, 0 - отсутствовал):
В результате наблюдений было замечено, что негативный эффект от декодирования не будет проявятся если таблица содержит не более 8 BIT столбцов. Попутно стоит отметить, что в метаданных SQL Server тип данных BIT используется очень редко - чаще применяют тип BINARY и вручную делают сдвиг для получения того или иного значения. И последнее о чем нужно упомянуть. Удаляйте ненужные данные. Собственно, зачем это делать? При выборке данных, SQL Server поддерживает механизм оптимизации производительности, называемый упреждающим чтением, который пытается предугадать, какие именно страницы данных и индексов понадобятся для выполнения запроса, и помещает эти страницы в буферный кэш, прежде чем в них возникнет реальная необходимость. Соответственно, если таблица содержит много лишних данных - это может привести к ненужным дисковым операциям. Кроме того, удаление ненужных данных позволяет сократить количество логических операций при чтении данных из Buffer Pool - поиск и выборка данных будет проходить по меньшему объёму данных. В заключение, что могу еще добавить - внимательно выбирайте типы данных для столбцов в Ваших таблицах и старайтесь учитывать будущие нагрузки на базу данных. Ссылки по теме |
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
О нас |
Интернет-магазин ITShop.ru предлагает широкий спектр услуг информационных технологий и ПО.
На протяжении многих лет интернет-магазин предлагает товары и услуги, ориентированные на бизнес-пользователей и специалистов по информационным технологиям. Хорошие отзывы постоянных клиентов и высокий уровень специалистов позволяет получить наивысший результат при совместной работе. В нашем магазине вы можете приобрести лицензионное ПО выбрав необходимое из широкого спектра и ассортимента по самым доступным ценам. Наши менеджеры любезно помогут определиться с выбором ПО, которое необходимо именно вам. Также мы проводим учебные курсы. Мы приглашаем к сотрудничеству учебные центры, организаторов семинаров и бизнес-тренингов, преподавателей. Сфера сотрудничества - продвижение бизнес-тренингов и курсов обучения по информационным технологиям.
|
119334, г. Москва, ул. Бардина, д. 4, корп. 3 +7 (495) 229-0436 shopadmin@itshop.ru |
|
© ООО "Interface Ltd." Продаем программное обеспечение с 1990 года |