Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Как определить какой запрос является более эффективным?  [new]
sash_kr
Member

Откуда:
Сообщений: 9
Имеется задача.

Есть таблица документов - Docs
Есть таблица некоторого документа - Doc1. У нее есть поле которое 'docID' которое связано с полем 'id' таблицы 'Docs'.
И есть таблица примечаний - Notes. У нее также есть такое же поле.

Нужно в одном запросе выбрать документы из таблицы 'Doc1', так чтобы в этом запросе была колонка с информацией, типа 1 или 0 в зависимости от того есть хоть одно примечание к этому документу или нет.

Сначала я написал так:

SELECT t1.docID, t1.column1, t2.column2, CASE WHEN t2.docID is null THEN 0 ELSE 1 END HasNotes
FROM
(
SELECT d1.docID, d1.column1, d2.column2
FROM Doc1 d1
    INNER JOIN Docs d ON d1.docID = d.id
WHERE d1.createDate > '20120101'
) t1
LEFT OUTER JOIN
(
SELECT n.docID
FROM Notes n
    INNER JOIN Doc1 d1 ON n.docID = d1.docID
        INNER JOIN Docs d ON d1.docID = d.id
WHERE d1.createDate > '20120101'
GROUP BY n.docID
) t2
ON t1.docID = t2.docID



Но потом я подумал, что может этот запрос будет эффективней:

SELECT t1.docID, t1.column1, t2.column2, CASE WHEN t2.docID is null THEN 0 ELSE 1 END HasNotes
FROM
(
-- Оставляем все как есть 
SELECT d1.docID, d1.column1, d2.column2
FROM Doc1 d1
    INNER JOIN Docs d ON d1.docID = d.id
WHERE d1.createDate > '20120101'
) t1
LEFT OUTER JOIN
(
-- Убираем все лишние join, where
SELECT n.docID FROM Notes n GROUP BY n.docID
) t2
ON t1.docID = t2.docID


То есть, может если я не буду писать второй раз условие выборки, то это и скажется на производительности?

И как вообще определить более эффективный запрос???
8 фев 12, 23:21    [12058740]     Ответить | Цитировать Сообщить модератору
 Re: Как определить какой запрос является более эффективным?  [new]
Гавриленко Сергей Алексеевич
Member

Откуда:
Сообщений: 37254
План покажет, какой.
8 фев 12, 23:25    [12058746]     Ответить | Цитировать Сообщить модератору
 Re: Как определить какой запрос является более эффективным?  [new]
iljy
Member

Откуда:
Сообщений: 8711
sash_kr,

SET STATISTICS TIME ON
SET STATISTICS IO ON

И планы смотреть.
8 фев 12, 23:28    [12058754]     Ответить | Цитировать Сообщить модератору
 Re: Как определить какой запрос является более эффективным?  [new]
sash_kr
Member

Откуда:
Сообщений: 9
В том то и дело, что в планах я разбираюсь очень плохо. Свое время когда я хотел найти хоть какую нибудь внятную инфу на эту тему – ничего не нашел.
8 фев 12, 23:50    [12058826]     Ответить | Цитировать Сообщить модератору
 Re: Как определить какой запрос является более эффективным?  [new]
Crimean
Member

Откуда:
Сообщений: 13147
профайлер и смотрим стоимости и время выполнения. все понятно. чем быстрее и дешевле - тем эффективнее
9 фев 12, 00:08    [12058888]     Ответить | Цитировать Сообщить модератору
 Re: Как определить какой запрос является более эффективным?  [new]
aleks2
Guest
sash_kr
Но потом я подумал, что может этот запрос будет эффективней:

SELECT t1.docID, t1.column1, t2.column2, CASE WHEN t2.docID is null THEN 0 ELSE 1 END HasNotes
FROM
(
-- Оставляем все как есть 
SELECT d1.docID, d1.column1, d2.column2
FROM Doc1 d1
    INNER JOIN Docs d ON d1.docID = d.id
WHERE d1.createDate > '20120101'
) t1
LEFT OUTER JOIN
(
-- Убираем все лишние join, where
SELECT n.docID FROM Notes n GROUP BY n.docID
) t2
ON t1.docID = t2.docID


И как вообще определить более эффективный запрос???


1. Группирова - зло.
2.
SELECT t1.docID, t1.column1, t2.column2, CASE WHEN exists(select * FROM  Notes  n WHERE n.docID = t1.docID) THEN 1 ELSE 0 END HasNotes
FROM
(
-- Оставляем все как есть 
SELECT d1.docID, d1.column1, d2.column2
FROM Doc1 d1
    INNER JOIN Docs d ON d1.docID = d.id
WHERE d1.createDate > '20120101'
) t1
9 фев 12, 06:33    [12059133]     Ответить | Цитировать Сообщить модератору
 Re: Как определить какой запрос является более эффективным?  [new]
sash_kr
Member

Откуда:
Сообщений: 9
aleks2
SELECT t1.docID, t1.column1, t2.column2, CASE WHEN exists(select * FROM  Notes  n WHERE n.docID = t1.docID) THEN 1 ELSE 0 END HasNotes
FROM
(
-- Оставляем все как есть 
SELECT d1.docID, d1.column1, d2.column2
FROM Doc1 d1
    INNER JOIN Docs d ON d1.docID = d.id
WHERE d1.createDate > '20120101'
) t1



Оказывается есть еще и третий вариант :-). Только вот мне всегда казалось что подвыборка в SELECT – это еще большее зло.
9 фев 12, 15:16    [12063061]     Ответить | Цитировать Сообщить модератору
 Re: Как определить какой запрос является более эффективным?  [new]
Crimean
Member

Откуда:
Сообщений: 13147
sash_kr
мне всегда казалось что подвыборка в SELECT – это еще большее зло.


ой это все так меняется от версии к версии.. мне вот тоже "казалось" что select min(a) / select top 1 a order by a при наличии индекса по "а" должны работать одинаково - а вот индейская народная изба вам..
9 фев 12, 15:20    [12063098]     Ответить | Цитировать Сообщить модератору
 Re: Как определить какой запрос является более эффективным?  [new]
_nobody_
Guest
sash_kr
Оказывается есть еще и третий вариант :-). Только вот мне всегда казалось что подвыборка в SELECT – это еще большее зло.

А я до сих пор так считаю.

Смотрите планы тынц.4
9 фев 12, 15:31    [12063219]     Ответить | Цитировать Сообщить модератору
 Re: Как определить какой запрос является более эффективным?  [new]
sash_kr
Member

Откуда:
Сообщений: 9
_nobody_
Смотрите планы тынц.4


Спасибо. Буду читать. Правда хотелось бы чего-то с примерами и детальными описаниями. Но может что то такое и найду.

P.S.
Кстати ссылка меня удивила. Этакий animation of google search
9 фев 12, 16:09    [12063767]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить