2012-04-22 6 views
-1

У меня есть таблица SpecialOffers и стол для акционных элементов под названием SOItems И я хочу, чтобы получить специальное предложение для конкретного объекта, если я нашел, что это так, первый я сделал это:Несколько SQL запросов или объединений?

IF EXISTS(SELECT * FROM SOTtems WHERE ItemType = 2 AND Itemid = @id) 
BEGIN 
     INSERT INTO #SO 
     SELECT * FROM SpecialOffers so 
     INNER JOIN SOItems soi ON so.Id = soi.SpecialOfferID 
     WHERE soi.ItemType = 2 AND soi.Itemid = @id 
END 

Но чтобы избавиться от из INNER JOIN, потому что я думал, что это лучше для производительности я сделал это:

DECLARE @specialOfferID INT 

SET @specialOfferID = (SELECT SpecialOfferID FROM SOTtems WHERE ItemType = 2 AND Itemid = @id) 

IF @specialOfferID IS NOT NULL 
BEGIN 
    INSERT INTO #SO 
    SELECT * FROM SpecialOffers so 
    WHERE ID = @specialOfferID 
END 

Так что более эффективно и лучше для производительности, чтобы выполнить более SQL запросов или использовать присоединиться к этому примеру и вообще

Примечание: в хранимой процедуре я пишу я должен это более чем в 6 раз, поэтому я спросил у :)

благодаря

ответ

1

Эта оптимизация рука, вероятно, нет необходимости, поскольку оптимизатор больше способный справиться с этим.

Вы можете поместить оба в SSMS и запустить их вместе и посмотреть на относительные затраты в плане выполнения.

Избегание соединений обычно не является первым шагом в оптимизации.

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

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

Я бы на самом деле упростить ее вниз только:

INSERT INTO #SO 
SELECT * 
FROM SpecialOffers so 
INNER JOIN SOItems soi 
    ON so.Id = soi.SpecialOfferID 
    AND soi.ItemType = 2 
    AND soi.Itemid = @id 

Вот именно - не СУЩЕСТВУЕТ чек или что-нибудь еще - внутреннее соединение означает, что проверка на существование является излишним, так как это ничего не будет вставлять иначе , Это делает более удобный код в одном смысле, потому что вам не нужно будет дублировать условие, если оно изменится, а код в соединении вряд ли будет изменен случайно. С другой стороны, если соединение будет изменено, это может иметь более серьезные последствия.

Обратите внимание: вы все равно можете записать это как версию WHERE без использования проверки EXISTS.

Меньше кода обычно означает меньше мест для скрытия ошибок.

+0

Спасибо большое, я согласен с вами, но я не оптимизирую, пока у меня не возникнет проблема с производительностью, я не согласен, я имею в виду, если вы сначала напишете свой код, у вас не будет проблем с производительностью в будущем, то вам не нужно оптимизировать – AlaaL

+0

@ TheDarkLord Код должен работать правильно во-первых, быть ремонтопригодным и соответствовать основным передовым практикам. Все после этого - оптимизация. Но вы правы, после многих (14, может быть?) Лет с SQL Server мое определение основных лучших практик обычно является достаточным, чтобы избежать дальнейшей оптимизации. –

+0

Спасибо за помощь. – AlaaL

1

Пройдите оба запроса в окне в Studio Management и отобразите план выполнения запроса. Это точно скажет вам, что происходит.

Скорее всего, вы увидите, что разница в производительности очень мала. Что может сделать второй несколько быстрее, так это то, что он не имеет IF EXISTS(...), но, с другой стороны, этот результат будет кэшироваться, поэтому разница все еще мала.

Другая вещь, которая может изменить ситуацию, заключается в том, что вы помещаете больше данных в таблицу #SO с первым запросом. Когда вы используете SELECT *, вы получаете больше данных, чем вам нужно. Например, включены оба поля SOItems.SpecialOfferID и SpecialOffers.Id, но вы знаете, что они всегда одинаковы. Укажите, какие поля вы хотите вернуть, чтобы вы не получали больше, чем вам нужно.

+0

Да, спасибо, на самом деле я не использую SELECT * в реальном коде, но я пишу его здесь, поэтому мне не нужно писать имена полей :) – AlaaL

+0

@ TheDarkLord: Приятно слышать. :) – Guffa

Смежные вопросы