Аргумент эффективности SQL, добавить столбец или разрешимый запрос? - PullRequest
0 голосов
/ 29 марта 2010

Я недавний выпускник колледжа и новый сотрудник по разработке программного обеспечения. В последнее время все было немного медленно, поэтому мне дали задание по БД. Мои навыки работы с БД ограничены проектами с питомцами Rails и Django. Итак, я был немного удивлен своим последним заданием.

Мой менеджер попросил подкласса Person с таблицей 'Parent' и добавить ссылку на своего хранителя в таблицу Person. Это облегчает переход от Родителя к Форме, когда Хранителем, а не Родителем, является FormContact.

Вот упрощенная, фиктивная структура sql-db, с которой я работаю. Я бы нарисовал таблицы отношений, если бы у меня был доступ к Visio.

У нас есть таблица «Персона» и таблица «Форма». Существует таблица «FormContact», которая связывает Персона с Формой, не все Персоны связаны с Формой. Существует таблица отношений для отношений между людьми (работодатель, родитель и т. Д.)

Я спросил: «Почему это не может быть обработано запросом?» Реакция неэффективна. (Действительно!?!)

Итак, я спрашиваю: «Почему бы не иметь ссылку на форму? Это было бы более эффективно, поскольку вы не стали бы запрашивать таблицу FormContacts со ссылкой ребенка / опекуна». Ответ, это по существу сделало бы, что Родитель является FormContact. (Достаточно справедливо.)

Я написал запрос, чтобы перейти от родителя, не являющегося FormContact, к форме и протестировал его на рабочем сервере. Время отклика было мгновенным. SOME_VALUE - это идентификационный номер родителя.

SELECT FormID 
FROM FormContact 
WHERE FormContact.ContactID 
    IN (SELECT SourceContactID 
        FROM ContactRelationship
        WHERE (ContactRelationship.RelatedContactID = *SOME_VALUE*) 
            AND (ContactRelationship.Relationship = 'Parent'));

Если я прав, «Это ненужное изменение». Что мне делать, защищать свою должность или уступать запросу менеджера?

Если я не прав. В чем моя ошибка? Есть ли лучшее решение, чем у менеджера?

1 Ответ

2 голосов
/ 29 марта 2010

Перво-наперво, ваш запрос может быть переработан. Вместо того, чтобы выбирать, попробуйте использовать join:

SELECT FormID

FROM FormContact fc

JOIN ContactRelationship cr on cr.SourceContactID = fc.ContactID 
                               and cr.Relationship = 'Parent'

WHERE cr.RelatedContactID = @parent_id

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

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

При этом я не вижу, как объединение таблицы Person в столбце ParentID (я полагаю, это то, что вы добавляете) обеспечило бы повышение производительности по сравнению с объединением, перечисленным выше, при условии, что рассматриваемые столбцы правильно проиндексированы.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...