powered by simpleCommunicator - 2.0.41     © 2025 Programmizd 02
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Позор джунглям!!!
12 сообщений из 12, страница 1 из 1
Позор джунглям!!!
    #32000803
dmitry
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Смотрел сейчас планы выполнения запросов и натолкнулся на такую фишку: запрос Select * from Table where a=2 and a=3. Самый простейший пример, который описывается во введении любой статьи про оптимизацию запросов. Ну типа как 2*2=4. И говорят, что вот при подобных случаях можно упрстить условие (в данном случае будет просто False). А что же хваленый SQL-оптимизатор? Он говорит что надо сканитровать таблицу + compute scalar! И показывает определенную нагрузку на эти опреации. Если а-индекс - то соответсвенно Index seek и Bookmark lookup. Или другой пример - select * from Table where 2=3. Так его еще не обмануть (слава богу) - дает план с Constant scan и нулевой нагрузкой. (кстати кто подскажет какой смысл имеет эта операция?) Так вот если чуть-чуть усложнить:
Select * from Table where sin(2)=sin(3), то он начинает делать Table Scan!! После чего накладывает фильтр. Это вместо того, чтобы один раз посчитать значение предиката where. (Заметьте, во where не используется значение столбцов, только константы и функции от них). Так то вот... Разочаровал он меня
...
Рейтинг: 0 / 0
Позор джунглям!!!
    #32000807
Павел
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Круто... А как там Oracle ? Я копаю IB и ASA но там план не посмотрищь.
...
Рейтинг: 0 / 0
Позор джунглям!!!
    #32000828
Fompro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Раньше в статьях просто указывалось, что для отключения индекса достаточно в критерий вставить вычисляемое выражение типа А*1=3. Думаю, что-то подобное осталось.
...
Рейтинг: 0 / 0
Позор джунглям!!!
    #32000844
dmitry
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да, про это уже упомянул Oleg F в разделе "Как изменить формат даты" (авор раздела Sasha).
Но речь не о том. Я просто говорю, что оптимизатор SQL сервера не делает элементарных упрощений, которые могут кстати дать огромный выигрыш в производительности. (При этом я вовсе не утверждаю что он ваще ничего не делает - более сложные виды оптимизации он проводит, хотя теперь я уже сомневаюсь насколько велик перечень этих видов). А насчет того, что поставить вместо A=3 => A*1=3, так это не подход.
Во-первых, оптимизацией должен заниматься оптимизатор. Человек по возможности, конечно, должен писать запросы пограмотнее, но он никак уж не должен смотреть будет ли оптимизатор выполнять свою работу или нет и если нет, то пытаться сделать это вместо него.
Во-вторых, отключение работы индекса никогда не приведет к увеличению скорости обработки
В-третьих, отключение работы индекса в данном конкретном примере просто заставит не делать поиск по индексу, а делать сканирование таблицы, что его еще больше затормозит.
...
Рейтинг: 0 / 0
Позор джунглям!!!
    #32000853
Фотография SergSuper
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 Dmitry

Небольшая поправка.
Полное простое сканирование таблицы однозначно быстрее, чем её же проход по индексу - в последнем случае вместе с таблицей нужно читать еще и индекс.
Ну и не согласен я, что оптимизатор в основном должен оптимизацией заниматься. Можно такого нагородить, что никакой оптимизатор не разбереться. Нужно всё-таки с умом писать и представлять, чем же может помочь оптимизатор. А если из вредности ему писать вместо А - А*1 - не думаю, что это правильный подход.

Кстати план планом, а я у себя написал запрос:
Select *
from sysobjects s1,sysobjects s2,sysobjects s3,sysobjects s4,sysobjects s5
where sin(2)=sin(3)

На план смотреть было страшно. Количество строчек для перебора получается 7,028,611,650,851. Засеките у себя время выполнение такого запроса - потом делайте выводы насчет оптимизации.


2 Fompro
Если написать во where что-нибудь типа id*1<>id - разница будет небольшая.

С приветом Сергей
...
Рейтинг: 0 / 0
Позор джунглям!!!
    #32000857
VadimB
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Оптимизатор использует различную статистику.
Если кол-во записей небольшое, то оптимизатор может просто игнорировать любые индексы.
Птестируйте оптимизатор на таблицах с несколькими милионами записей.
...
Рейтинг: 0 / 0
Позор джунглям!!!
    #32000860
Nick
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
гхм... )) народ по поводу
select * from sysobjects s1,sysobjects s2,sysobjects s3,sysobjects s4,sysobjects s5
where sin(2)=sin(3)
)) у меня лично выполняется 20мс... ))
ну действительно план он зря создает )) такой ))
но он его не выполняет !!! он обрубается на where !!! и все !
так что кто-то тут гонит )) ))

С уважением Прайс Николай.
...
Рейтинг: 0 / 0
Позор джунглям!!!
    #32000868
dmitry
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
"Ну и не согласен я, что оптимизатор в основном должен оптимизацией заниматься. "
Я имел ввиду, что человек не должен подгадывать сможет ли оптимизатор оптимизировать кусок запроса, или решит, что "жираф большой, ему видней" и оставит все как есть даже не попытавшись сделать лучше.

"у меня лично выполняется 20мс". А как померить время с точностью меньше секунды?

"ну действительно план он зря создает )) такой ))
но он его не выполняет !!! " Так к чему мы пришли? К тому что то, что называется планом, на самом деле просто хрень, которая подсовывается доверчивым пользователям, а на самом деле у него есть другой, настоящий план по которому он и работает ?
) Похоже что именно так и есть.
Тут вот сделал еще такую штуку: есть таблица без индекса. Создаю такую же но с индексом и копирую все данные из первой во вторую. Пишу запрос где WHERE поле с индексом сравнивается с константой. Смотрю план работы запроса для первой таблицы(без индекса) и сравниваю с таким же но для второй. Они идентичны!!!???!!! Никаких операций с индексом во второй таблице... Выпадаю в осадок, но думаю вдруг действительно так лучше... Запускаю первый запрс - время работы 8с. Второй - 4с!!!! И какими ругательными словами называть после этого тот бред, который выдает построитель планов?

Насчет того, что при небольшом числе записей индекс игнорируется: я теперь уже не верю этому "плану", но он говорит что будет его использовать даже при одной записи.
...
Рейтинг: 0 / 0
Позор джунглям!!!
    #32000869
dmitry
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А насчет вместо A писать A*1, так это не из вредности. Если например учитель приходит в новый класс, то он сначала посмотрит что могут ученики, и если окажется, что они не знают что такое таблица умножения, то навряд ли будет задавать решение тригонометрических уравнений. Так и тут это просто наиболее примитивный пример, который как оказалось оптимизатор не решил. Если бы решил, то можно написать чего посложнее и посмотреть как справится с этим и т.д. Человек должен писать по возможности лучше (это я уже писал), а оптимизатор должен иметь возможность подкорректировать если что не так. A даже насчет оптимизации логических выражений не всегда сходу можно навскидку сказать оптимальный вариант. Для этого есть свой мат. аппарат.
...
Рейтинг: 0 / 0
Позор джунглям!!!
    #32000896
dmitry
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
"Кстати план планом, а я у себя написал запрос:
Select * from sysobjects s1,sysobjects s2,sysobjects s3,sysobjects s4,sysobjects s5
where sin(2)=sin(3)
На план смотреть было страшно. Количество строчек для перебора получается 7,028,611,650,851. Засеките у себя время выполнение такого запроса - потом делайте выводы насчет оптимизации."

Ага, а теперь если есть одна табличка строчек так миллиона на 2, за 3, попробуйте сделать тоже самое с ней (достаточно только один раз упомянуть во from (без s1, s2,...))
Результаты совсем другие. А именно: Если таблица содержит примерно 1 млн (размер записи - 66 байт), то в первый раз выполняется секнд 7, а потом, в следующие разы - меньше чем за 1с. (Судя по всему просто данные в ОП подтянул). А вот если записей около 2.5 млн., то всегда выполняется примерно за 14 с. (Судя по всему ОП не хватает, вот и обращается постоянно к диску).
Тут выводы напрашиваются совсем другие...
...
Рейтинг: 0 / 0
Позор джунглям!!!
    #32000924
Nick
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Народ... да хватит вам е-мое уже все кости ему промыли... гыгыгы ))
Ну глюкало... и че дальше ?? перед тем как использовать запрос в прило-
жении просто всегда необходимо посмотреть на его план и попробывать
оптимизировать его... порой даже с помощью идиотских вариаций
с синтаксисом... ну такой он... ну чего вы пристали...
А к вопросу как померить точное время, то в SQL-Analyzer'е в меню
включается, там же где и включается просмотр плана...
...
Рейтинг: 0 / 0
Позор джунглям!!!
    #32001477
Фотография Дед Маздай
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Прошу прощения за реанимацию давно угаснувшей дискуссии, я просматривал архив и это сообщение меня заинтересовало. Dmitry действительно обнаружил очень любопытный факт, но сделал из него абсолютно неверные выводы. Ближе всех к истине подошел Nick, но в конце почему-то сдался. Во-первых, отбросим несущественное. Индексы и SARGи здесь ни при чем. Вопрос состоит в следующем: выполняет ли SQL Server запросы с where = <false>. Надеюсь, понятно о чем речь, а то мне тут один заявил, типа, ясен пень, что нет, он же пишет: 0 rows affected. Я категорически не согласен с оценками типа "Позор джунглям", "Глюкало" и утверждаю, что процессор запросов оценивает константу фильтра априори без последующего сравнения row by row и траты на это циклов процессора и прочих системных ресурсов. Проведем следующий эксперимент: включим в QA Show Server Trace (Ctrl-Shift-T) и Show Execution Plan (Ctrl-K) для вывода времени выполнения запроса и показа реального плана выполнения. Да, Dmitry, estimated execution plan может иногда не совпадать с фактическим, это не бред, а просто жизнь так устроена, что не всегда на стадии компиляции его можно построить однозначно. Например, если запрос с параметрами или SQL Server сам решает использовать автопараметризацию, то, очевидно, что это значения параметров выяснятся только во время run-time. Возможны и другие причины. Возьмем запрос select * from orders o1, orders o2, orders o3, orders o4, orders o5 where sin(0)=sin(1) и посмотрим estimated plan. Мать моя, оказывается, он собирается вернуть 3.9Е+14 записей. Полный бред, суксь, маздай, кто так строит, наберут, блин, по объявлению и пр. А теперь не побоимся его выполнить и посмотрим реальный план (закладка Execution Plan в панели результатов). Вы видите, что фактический row count везде = 0. Хорошо, но, может быть, SQL Server все-таки выполнял этот запрос? Нет. Смотрите, Number of executes у самого правого верхнего оператора Index Scan = 0. Для иллюстрации сравним, напр., с select * from orders o1, orders o2, orders o3, orders o4, orders o5 where o1.freight=sin(1). Несмотря на то, что row count здесь тоже = 0, Number of executes = 1, так что данный запрос в отличие от предыдущего действительно выполняется. Почистим процедурный кэш, свободные буфера и сравним время выполнения (закладка trace). Оно, конечно, зависит от вашей тачки, но я уверен, что для второго запроса Duration, CPU, Reads у вас будут превышать аналогичные показатели для первого.
...
Рейтинг: 0 / 0
12 сообщений из 12, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Позор джунглям!!!
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]