#sql #performance
#sql #Производительность
Вопрос:
У меня есть таблица атрибутов, в которой есть набор атрибутов, идентифицируемых уникальным номером, за которым следует их описание — Пример схемы
ID - AttributeName
с некоторыми примерами данных ниже
1 = FirstName
2 = LastName
3 = Phone
Затем у меня есть таблица employees, которая для простоты имеет следующую схему
ID - PersonID
AttribueID - INT Foreign key to the above attributes table
Мне нужно создать сохраненный процесс, который при заданном условии будет возвращать записи на основе одного из следующих условий
Если я передам 1 хранимой процедуре, процедура должна вернуть все записи из таблицы Person, которые соответствуют идентификатору атрибута 1 (Имя) Если я передам 2 хранимой процедуре, процедура должна вернуть все записи из таблицы Person, которые * НЕ * соответствуют идентификатору атрибута 1 (Имя) Если я передам 3 в хранимую процедуру, процедура должна вернуть все записи из таблицы Person
Я мог бы сделать следующее, но чувствую, что это не лучший способ, которым это можно было бы выполнить
DECLARE @IntID INT = 1 -- Set as 1 just for exmple
IF @IntID =1
BEGIN
SELECT * FROM Person where AttributeID IN (SELECT ID from Attributes Where ID =1) -- match on attribute 1
END
ELSE IF @IntID = 2
BEGIN
SELECT * FROM Person where AttributeID NOT IN (SELECT ID from Attributes Where ID =1) -- do not match on attribute 1
END
ELSE
BEGIN
SELECT * FROM Person where AttributeID IN (SELECT ID from Attributes) -- return match on all attributes
END
Приведенный выше пример содержит чрезвычайно простую инструкцию SELECT — в реальном SQL существует гораздо больший набор
Заранее спасибо
Ответ №1:
Если вы не хотите использовать динамический sql, вы можете попробовать это. И ваш запрос слишком прост, что для оптимизации производительности вы можете обратиться к табличным индексам для этого.
DECLARE @IntID INT = 1 -- Set as 1 just for exmple
IF @IntID = 1 OR @IntID = 2
BEGIN
SELECT A.*
FROM Person A
LEFT JOIN Attributes B ON A.AttributeID = B.ID AND B.ID = 1
WHERE
A.AttributeID IS CASE @IntID WHEN 1 THEN NOT NULL WHEN 2 THEN NULL END
END
ELSE
BEGIN
SELECT A.*
FROM Person A
INNER JOIN Attributes B ON A.AttributeID = B.ID
END
Комментарии:
1. Объединение нескольких обращений в один универсальный выбор может привести к неоптимальному плану выполнения, я бы вообще рекомендовал избегать этого.