Непристойное поведение select в mssql

Работа VB и СУБД (Access, MSSQL, MySQL, Oracle и пр.)
Правила форума
При создании новой темы не забывайте указывать используемую СУБД.
Antonariy
Повелитель Internet Explorer
Повелитель Internet Explorer
Аватара пользователя
 
Сообщения: 4824
Зарегистрирован: 28.04.2005 (Чт) 14:33
Откуда: Мимо проходил

Непристойное поведение select в mssql

Сообщение Antonariy » 01.09.2006 (Пт) 12:52

Есть процедура такого вида:
alter PROCEDURE udGetList
@ProjectID int,
@OperatorID int=0
AS

declare @optype int
select @optype = OperatorTypeID from tblOperators where OperatorID=@OperatorID

select * from cvOrganisationsList
where ProjectID = @ProjectID and (
OperatorID = @OperatorID or
OperatorID = null or
@OperatorID = 0 or
@optype=1)
Если убрать выделенную строчку, то записи возвращаются в порядке, предусмотренном индексами. А при ее наличии записи возвращаются в произвольном порядке, всегда разном. С чем это связано?
Лучший способ понять что-то самому — объяснить это другому.

Ennor
Конструктивный критик
Конструктивный критик
 
Сообщения: 2504
Зарегистрирован: 18.12.2001 (Вт) 3:58
Откуда: Калуга -> Москва

Re: Непристойное поведение select в mssql

Сообщение Ennor » 01.09.2006 (Пт) 17:48

Antonariy писал(а):в порядке, предусмотренном индексами.
Нет такого порядка больше, и уже давно. Начиная с версии 7.0, сиквел не гарантирует никакого порядка, если явно не указан ORDER BY. Просто прими это как данность и не парься больше.

Т.е. он и раньше ничего не гарантировал, но внутренняя зависимость была, и довольно простая. Теперь там все сложнее.

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 01.09.2006 (Пт) 20:23

И... можно нескромный вопрос...
OperatorID = null

Это когда-то выполняется?..
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

VVitafresh
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1641
Зарегистрирован: 12.05.2005 (Чт) 14:44
Откуда: Херсон, UA

Сообщение VVitafresh » 01.09.2006 (Пт) 21:13

GSerg писал(а):И... можно нескромный вопрос...
OperatorID = null

Это когда-то выполняется?..

Неа.
Код: Выделить всё
OperatorID IS NULL
Никакую проблему невозможно решить на том же уровне, на каком она возникла. Нужно стать выше этой проблемы, поднявшись на следующий уровень.

Ennor
Конструктивный критик
Конструктивный критик
 
Сообщения: 2504
Зарегистрирован: 18.12.2001 (Вт) 3:58
Откуда: Калуга -> Москва

Сообщение Ennor » 02.09.2006 (Сб) 9:02

Епрст. Antonariy, прикалываешься?
where ProjectID = @ProjectID and (
OperatorID = @OperatorID or
OperatorID = null or
@OperatorID = 0 or
@optype=1)
Ты в условии запроса проверяешь значение переменной, а не столбца. Неудивительно, что план начинает строиться совершенно по-другому :lol:

Да, и последнее: данный набор OR'ов (за вычетом этой проверки, разумеется) можно заменить такой вот изящной конструкцией:
Код: Выделить всё
where ProjectID = @ProjectID
  and (nullif(OperatorID, @OperatorID) is null
    or @optype=1)

Вообще же считается, что MSSQL плохо переваривает OR-условия; так что, если будут проблемы с производительностью, попробуй переписать запрос в виде UNION.

Antonariy
Повелитель Internet Explorer
Повелитель Internet Explorer
Аватара пользователя
 
Сообщения: 4824
Зарегистрирован: 28.04.2005 (Чт) 14:33
Откуда: Мимо проходил

Сообщение Antonariy » 02.09.2006 (Сб) 9:47

GSerg писал(а):И... можно нескромный вопрос...
OperatorID = null

Это когда-то выполняется?..
:D Постоянно переключаюсь sql - javascript - vb. Уже иногда в вб пишу if x==
Нет такого порядка больше, и уже давно.
По-моему теперь прикалываешься ты. select * from tbl всегда возвращает записи в порядке, указанном кластерным индексом. А кластерный индекс и физически и логически выстраивает записи указанным порядком. В чем по-твоему смысл сортировки полей индексов, если они нихрена не гарантируют?
Ты в условии запроса проверяешь значение переменной, а не столбца. Неудивительно, что план начинает строиться совершенно по-другому :D
Все прикалываешься? А как насчет @optype=1? Ее наличие/отсутствие на порядок не влияет.
Лучший способ понять что-то самому — объяснить это другому.

Antonariy
Повелитель Internet Explorer
Повелитель Internet Explorer
Аватара пользователя
 
Сообщения: 4824
Зарегистрирован: 28.04.2005 (Чт) 14:33
Откуда: Мимо проходил

Сообщение Antonariy » 02.09.2006 (Сб) 9:55

Вопрос более не актуален. Переделал логику и нужда в проверке @OperatorID = 0 отпала.
Лучший способ понять что-то самому — объяснить это другому.

Konst_One
Член-корреспондент академии VBStreets
Член-корреспондент академии VBStreets
Аватара пользователя
 
Сообщения: 3041
Зарегистрирован: 09.04.2004 (Пт) 13:47
Откуда: Химки

Сообщение Konst_One » 04.09.2006 (Пн) 11:19

нет порядка записей в возвращаемом резалтсете в сиквеле :!:
всегда случайным образом :!:

если нужен порядок, то обязательно надо использовать сортировку:
Код: Выделить всё
ORDER BY Field1 ASC{DESC}

Antonariy
Повелитель Internet Explorer
Повелитель Internet Explorer
Аватара пользователя
 
Сообщения: 4824
Зарегистрирован: 28.04.2005 (Чт) 14:33
Откуда: Мимо проходил

Сообщение Antonariy » 04.09.2006 (Пн) 11:45

Если в ста случаях из ста записи возвращаются в ожидаемом порядке, о какой случайности может идти речь? Или ты имеешь ввиду, что каждый раз случайно записи возвращаются без order by так как угодно мне? Обоснуй доказательно свои слова. Лично я руководствуюсь этим:
BOL писал(а):Clustered indexes have one row in sysindexes with indid = 1. The pages in the data chain and the rows in them are ordered on the value of the clustered index key. All inserts are made at the point the key value in the inserted row fits in the ordering sequence.
Лучший способ понять что-то самому — объяснить это другому.

Konst_One
Член-корреспондент академии VBStreets
Член-корреспондент академии VBStreets
Аватара пользователя
 
Сообщения: 3041
Зарегистрирован: 09.04.2004 (Пт) 13:47
Откуда: Химки

Сообщение Konst_One » 04.09.2006 (Пн) 12:20

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

Любая DBMS, основанная на стандартах SQL, выводит гарантированно сортированный набор данных только при наличии ORDER BY в предложении на выборку - это аксиома.
Из опыта могу заметить, что кластерный PK не является гарантией такого результата в MSSQL (как впрочем и в Oracle и тд и тп). Искать подтверждения моим словам можешь в документации по MSSQL на MSDN и в публикациях от мелкософта, но это точно где-то есть, поверь мне.
:wink:

Antonariy
Повелитель Internet Explorer
Повелитель Internet Explorer
Аватара пользователя
 
Сообщения: 4824
Зарегистрирован: 28.04.2005 (Чт) 14:33
Откуда: Мимо проходил

Сообщение Antonariy » 04.09.2006 (Пн) 13:12

Действительно, я слегка погорячился :oops:
На запросах, где join'ов побольше, записи возвращаются несортированные, но всегда в одном и том же порядке. Так что самый певый вопрос все равно меня смущает, хотя уже не актуален.
Лучший способ понять что-то самому — объяснить это другому.

HandKot
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 283
Зарегистрирован: 28.06.2006 (Ср) 13:34
Откуда: Sergiev Posad

Сообщение HandKot » 05.09.2006 (Вт) 14:54

Konst_One писал(а):
Любая DBMS, основанная на стандартах SQL, выводит гарантированно сортированный набор данных только при наличии ORDER BY в предложении на выборку - это аксиома.
Из опыта могу заметить, что кластерный PK не является гарантией такого результата в MSSQL (как впрочем и в Oracle и тд и тп). Искать подтверждения моим словам можешь в документации по MSSQL на MSDN и в публикациях от мелкософта, но это точно где-то есть, поверь мне.
:wink:


т.к в MS SQL существует оптимизатор запросов, то
оный оптимизатор и является причиной того, что записи возвращаются в одном и том же порядке + использование сервером КЭША (хотя в некоторых случаях порядок может и нарушаться)

Antonariy писал(а):Если убрать выделенную строчку, то записи возвращаются в порядке, предусмотренном индексами. А при ее наличии записи возвращаются в произвольном порядке, всегда разном. С чем это связано?


сравните планы выполнения запросов и может это чем-то вам поможет

Konst_One
Член-корреспондент академии VBStreets
Член-корреспондент академии VBStreets
Аватара пользователя
 
Сообщения: 3041
Зарегистрирован: 09.04.2004 (Пт) 13:47
Откуда: Химки

Сообщение Konst_One » 05.09.2006 (Вт) 15:12

и главное в самый неподходящий момент, как всегда :lol:


Вернуться в Базы данных

Кто сейчас на конференции

Сейчас этот форум просматривают: Google-бот и гости: 1

    TopList