Какую разницу в производительности можно ожидать от применения ограничений PK / FK по сравнению с невыполнением ограничений PK / FK, если таковые имеются? - PullRequest
0 голосов
/ 31 октября 2019

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

В настоящее время я понятия не имею, что произойдет с нашей системой, если мы решим на самом деле соединить все через надлежащее ограничение, но я спрашиваю следующее:

Будет ли какое-либо увеличение производительности,в реализации правильного ограничения?

Ответы [ 2 ]

2 голосов
/ 31 октября 2019

Первичные и внешние ключи не являются усилителями производительности, они не предназначены для повышения производительности, и причина их использования не связана с производительностью.

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

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

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

1 голос
/ 31 октября 2019

Будет ли какое-либо увеличение производительности при реализации правильного ограничения?

Да, скорее всего, будет.

Представьте, что вы хотите вставить "дочернюю" строкукоторый не может существовать без соответствующей «родительской» строки. Как бы вы проверили это в хранимой процедуре?

Ну, наивно, вы бы:

IF EXISTS (SELECT * FROM PARENT WHERE ...)
    INSERT INTO CHILD VALUES (...);
ELSE
    THROW ...;

Но, конечно, параллельная транзакция может удалить родительскую строку между IF и INSERT,поэтому вам нужно заблокировать родительскую строку:

...SELECT * FROM PARENT WITH(UPDLOCK)...

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

Разрешение принудительного использования базой данных FK, вероятно, позволит повысить параллелизм и повысить производительность.


В запросе SELECT также могут использоваться декларативные внешние ключи.

Если у вас есть INNER JOIN, но вы выбираете столбцы только из дочерней таблицы, оптимизатор запросов может полностью пропустить доступ к родительской таблице - он уже знает,что если дочерняя строка существует, родительская строка тоже должна существовать, поэтому ей не нужно явно проверять наличие родительских элементов.

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

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