Пожалуйста, помогите объяснить, если я уничтожаю мою схему БД ради производительности :( - PullRequest
1 голос
/ 09 июля 2009

У меня есть база данных в производстве почти 3 года, на Sql 2008 (был '05, до этого). Было хорошо, но не очень эффективно. Поэтому я настраиваю схему и запросы, чтобы ускорить некоторые вещи. Кроме того, оценка основных таблиц содержит около 1-3 строк по одной таблице (для оценки размеров).

Вот пример схемы базы данных (Соз, под NDA, поэтому я не могу отобразить оригинал): -

альтернативный текст http://img11.imageshack.us/img11/4608/dbschemaexample.png

На что следует обратить внимание (которые имеют непосредственное отношение к моей проблеме): -

  • Автомобиль может иметь 0 (NULL) или 1 радио. (Левое внешнее соединение)
  • Автомобиль может иметь 0 (NULL) или 1 Cupholder (левое внешнее соединение)
  • Автомобиль имеет 1 тип шин (внутреннее соединение).

Во-первых, это выглядит как нормализованная схема базы данных . Я сосу и теорию БД, так что я предполагаю, что это 3NF (по крайней мере) ... знаменитые последние слова:)

Теперь, это убивает мою производительность базы данных, потому что эти два внешних соединения и внутреннее соединение вызывают много вызовов И есть также еще несколько соединений во многих операторах.

Чтобы попытаться это исправить, я подумал, что можно попробовать и индексированное представление . Создание вида это кусок пирога. Но его индексация не работает -> не может создавать индексированные представления с объединениями ИЛИ самоссылающимися таблицами (также другая проблема :().

Итак, я плакал часами (и / запястья , окрашенные волосы и написал об этом эмо-песню и поместил ее в myfailspace) и сделал следующее ...

  1. Добавлена ​​новая строка в каждую «необязательную» таблицу внешних соединений (в этом примере Radios и CupHolders). ID = 0, остальные данные = «Неизвестный бла» или 0.
  2. Обновите родительские таблицы, чтобы любые нулевые данные теперь имели 0.
  3. Обновить отношение внешних соединений к внутренним соединениям.

Теперь это работает. Я даже могу сделать свое индексированное представление, которое сейчас очень быстро.

Итак ... мне больно. Это противоречит всему, чему меня учили. Я чувствую себя грязным В одиночестве. Зараженный.

Это плохо делать? Является ли это распространенным сценарием денормализации базы данных для повышения производительности?

Мне бы хотелось подумать об этом, пожалуйста:)

PS. Эти изображения, которые случайный гугл находит - не я.

Ответы [ 4 ]

2 голосов
/ 09 июля 2009

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

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

Я думаю, что это нормально.

1 голос
/ 09 июля 2009

База данных должна всегда быть спроектирована и изначально реализована в 3NF. Но мир - это место реальности, а не идеалов, и можно вернуться к 2NF (или даже 1NF) по соображениям производительности. Не мучайте себя этим, прагматизм все время побеждает догматизм в реальном мире.

Ваше решение, если оно улучшает производительность, является хорошим. Идея иметь реальное радио (например), изготовленное никем и не имеющее каких-либо особенностей, неплохая - раньше было сделано лот , поверьте мне :-) Единственная причина, по которой вы бы использовали В этом поле в качестве значения NULL указывалось, какие автомобили не имеют радиоприемника, и разница между этими запросами незначительна:

select Registration from vehicles where RadioId is null
select Registration from vehicles where RadioId = 0

Моей первой мыслью было просто объединить четыре таблицы в одну и повесить проблему дублирования данных. Большинство проблем с СУБД связаны с низкой производительностью, а не с недостатком места для хранения.

Возможно, оставьте это в качестве запасной позиции, если ваша текущая ненормализованная схема также станет медленной.

0 голосов
/ 10 сентября 2009

я сталкиваюсь с той же проблемой производительности против академического превосходства. у нас есть большой взгляд на базу данных клиентов с 300 столбцами и 91000 записей. мы используем внешние соединения для создания представления, и производительность довольно плохая. мы рассмотрели возможность перехода к внутренним соединениям, добавив фиктивные записи со значением ноль в столбцы, к которым мы присоединяемся (вместо нуля), чтобы включить уникальный индекс в представлении.

Я должен согласиться с тем, что, если производительность важна, иногда нужно делать странные вещи, чтобы это произошло. в конечном счете, те, кто оплачивает наши счета, не заботятся о том, совершенна ли архитектура.

0 голосов
/ 09 июля 2009

"... Так что я настраиваю схему и запросы, чтобы ускорить некоторые вещи ..." - я бы умолял об этом. Кажется, вы замедляете ситуацию. (Шучу.)

Мне нравится блог программиста баз данных. У него есть два столбца за и против нормализации, которые могут вам пригодиться:

  1. http://database -programmer.blogspot.com / 2008/10 / аргумент-для-normalization.html
  2. http://database -programmer.blogspot.com / 2008/10 / аргумент-для-denormalization.html

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

Прежде чем что-либо изменить, я просил SQL Server ОБЪЯСНИТЬ ПЛАН по каждому медленному запросу и использовать эту информацию, чтобы точно узнать, что следует изменить. Не угадай, потому что гуру нормализации сказал тебе об этом. Получите данные для резервного копирования того, что вы делаете. То, что вы делаете, звучит как оптимизация кода среднего уровня без профилирования. Чувства кишечника не очень точны.

...