Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
MSSQL2000: INNER JOIN vs. обычная запятая
|
|||
|---|---|---|---|
|
#18+
Привет люди! Кто-нибудь знает, в чём разница между запросом SELECT a.id FROM A,B WHERE A.id=B.id_a и запросом SELECT a.id FROM A INNER JOIN B ON A.id=B.id_a кроме того, что последний работает слегка медленнее. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.09.2001, 08:48 |
|
||
|
MSSQL2000: INNER JOIN vs. обычная запятая
|
|||
|---|---|---|---|
|
#18+
Никакой разницы нет. А если использовать outer join тогда будет. В BOL статья есть, название не помню точно, что то типа "ЭSpecifying join in clauses from and where." Прошу прощения за возможные ошибки, просто дома у меня нет BOL и посмотреть точно я не могу. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.09.2001, 09:23 |
|
||
|
MSSQL2000: INNER JOIN vs. обычная запятая
|
|||
|---|---|---|---|
|
#18+
BOL(SQL2000) - Accessing and Changing Relational Data - Query Fundamentals - Join Fundamentals - Specifying Joins in FROM or WHERE Clauses ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.09.2001, 09:32 |
|
||
|
MSSQL2000: INNER JOIN vs. обычная запятая
|
|||
|---|---|---|---|
|
#18+
Разница в общем-то совершенно очевидна, и Вы ее видите сами, потому что в первом случае Вы сначала просите построить декартово произведение таблиц, участвующих в запросе, которое затем отфильтровать по условию, указанному в WHERE. Другое дело, что ни в одной из нормальных СУБД процессор запросов не будет бросаться тотчас это делать (потому что очень дорого), а соптимизирует план, приведя его ко второму варианту. Поэтому оба запроса работают совершенно одинаково и по результатам, и по времени. То, что в Вашем случае 2-й запрос работал "слегка медленнее", я объясняю погрешностью эксперимента, разной нагрузкой со стороны прочих пользователей и прочими transient conditions. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.09.2001, 09:46 |
|
||
|
MSSQL2000: INNER JOIN vs. обычная запятая
|
|||
|---|---|---|---|
|
#18+
Разница (правда на SQL 7.0) в некоторых случаях значительная, например когда результат соединения требуется затем отфильтровать. Оказывается SQL Server чувствителен к порядку записи SQL - выражения. Если сначала отфильтровать, а затем соединить, то рост скорости выполнения запроса впечатляет. Пример: SELECT tblX.A, tblY.B FROM tblX,tblY WHERE tblX=const AND tblX.PK = tblY.PK быстрее (может быть существенно быстрее) чем SELECT tblX.A, tblY.B FROM tblX,tblY WHERE tblX.PK = tblY.PK AND tblX=const а этот работает также как INNER JOIN Хотя ведь это ж классическая оптимизация, но почему-то мой SQL Server 7.0 Desktop ее не сделал. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.09.2001, 18:11 |
|
||
|
MSSQL2000: INNER JOIN vs. обычная запятая
|
|||
|---|---|---|---|
|
#18+
Разница (правда на SQL 7.0) в некоторых случаях значительная, например когда результат соединения требуется затем отфильтровать. Оказывается SQL Server чувствителен к порядку записи SQL - выражения. Если сначала отфильтровать, а затем соединить, то рост скорости выполнения запроса впечатляет. Пример: SELECT tblX.A, tblY.B FROM tblX,tblY WHERE tblX=const AND tblX.PK = tblY.PK быстрее (может быть существенно быстрее) чем SELECT tblX.A, tblY.B FROM tblX,tblY WHERE tblX.PK = tblY.PK AND tblX=const а этот работает также как INNER JOIN Хотя ведь это ж классическая оптимизация, но почему-то мой SQL Server 7.0 Desktop ее не сделал. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.09.2001, 18:15 |
|
||
|
MSSQL2000: INNER JOIN vs. обычная запятая
|
|||
|---|---|---|---|
|
#18+
Разницы не дожно быть АБСОЛЮТНО НИКАКОЙ, т.к. эти запросы семантически одинаковы. Выполни со включенным Show Query Plan чтобы убедиться. Алексей. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.09.2001, 21:12 |
|
||
|
MSSQL2000: INNER JOIN vs. обычная запятая
|
|||
|---|---|---|---|
|
#18+
Alexei Я тоже на это надеялся, но в моем случае абсолютно верно, что скорости выполнения запросов существенно отличаются. У меня, правда, есть подозрение, что что-то не так с оптимизатором запросов. Еще один странный эффект я обнаружил. Запрос на SELECT MIN(Prim key) ... отрабатывает медленнее, чем SELECT TOP 1 ... ORDERED BY Prim Key ASC, хотя с помощью индекса MIN должен находить нужный элемент за один ход. Вот так. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.09.2001, 07:58 |
|
||
|
MSSQL2000: INNER JOIN vs. обычная запятая
|
|||
|---|---|---|---|
|
#18+
>skv@analyst.ru Между прочим я про это читал даже. Не помню к сожалению где.... Что-то типа "Администрирования SQL Server"... Но то что оптимизатор работает не адекватно в этих случаях - факт. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.09.2001, 10:08 |
|
||
|
MSSQL2000: INNER JOIN vs. обычная запятая
|
|||
|---|---|---|---|
|
#18+
Всем спасибо за комментарии. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.09.2001, 11:16 |
|
||
|
MSSQL2000: INNER JOIN vs. обычная запятая
|
|||
|---|---|---|---|
|
#18+
Чтобы убедиться в том, что оптимизатор работает адекватно, не требуется читать ничего, кроме плана запроса. Рассмотрим следующую пару: 1) select top 1 * from orders order by orderid 2) select min(orderid) from orders Разница в том, что во втором случае появляется дополнительный оператор: Stream Aggregate(DEFINE[Expr1002]=MIN([Orders].[OrderID]))) который на больших объемах может вызывать проигрыш во времени по сравнению с первым. Но, извините, вы же сами его спровоцировали, использовав статистическую ф-цию (min). Вы же не удивляетесь, что x**2 выполняется медленнее, чем x*x. Что касается собственно предмета спора, то запросы типа select * from customers c inner join orders o on c.customerid = o.customerid select * from customers c, orders o where c.customerid = o.customerid порождают абсолютно идентичный план выполнения. В данном случае: |--Merge Join(Inner Join, MERGE[c].[CustomerID])=([o].[CustomerID]), RESIDUAL[o].[CustomerID]=[c].[CustomerID])) |--Clustered Index Scan(OBJECT[Northwind].[dbo].[Customers].[PK_Customers] AS [c]), ORDERED FORWARD) |--Sort(ORDER BY[o].[CustomerID] ASC)) |--Clustered Index Scan(OBJECT[Northwind].[dbo].[Orders].[PK_Orders] AS [o])) Сие означает, что разница во времени их выполнения может обуславливаться только внешними факторами, но никак не по причине происков оптимизатора. Вне зависимости от порядка перечисления таблиц в запросе оптимизатор сам выберет наиболее дешевый порядок их связывания (который может отличаться в з-ти от доступной памяти, текущей нагрузки и т.д.), если только ему явно не воспрепятствовать: SET FORCEPLAN, либо option (force order). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.09.2001, 15:48 |
|
||
|
MSSQL2000: INNER JOIN vs. обычная запятая
|
|||
|---|---|---|---|
|
#18+
Вот как раз Stream Aggregate мне и не нравиться, в данной ситуации я бы предпочел Index Seek. Индекс у меня уникальный. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.09.2001, 19:22 |
|
||
|
MSSQL2000: INNER JOIN vs. обычная запятая
|
|||
|---|---|---|---|
|
#18+
Что касается плана запроса, то действительно QA их расписывает одинаково, и одинаково правильно. Но чем тогда вызвано отличие в скорости? Никаких хинтов и прочего для оптимизатора не задавалось. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.09.2001, 19:38 |
|
||
|
MSSQL2000: INNER JOIN vs. обычная запятая
|
|||
|---|---|---|---|
|
#18+
Либо я неточно выразился, либо Вы невнимательно прочитали. 1. Stream Aggregate неизбежен, коль скоро речь идет о статистической функции (min(), max(), sum(), count(), чего там еще...) Конечно, можно было оптимизировать ее работу в Вашем конкретном примере. Но, возвращаясь к моей иллюстрации cо степенью, это все равно, что проверять тип показателя и, если вещественный, то раскладывать в ряд, а если целый, то перемножать. Как правило, так никто не делает, потому что тогда компилятор бы раздулся до немеренных размеров, а потом - всех частностей все равно не учтешь. 2. Под внешними условиями я понимаю пользователей, другие приложения, W-бозоны и все прочее, что влияет на ресурсы SQL Server'a. Допустим, сейчас он выполняет запрос, распараллеливая его на 4 процессора, а через полчаса тот же запрос будет ворочаться на одном, потому что пришли еще 150 пользователей и все потоки отданы им под коннекты. Сейчас он у Вас вяжет таблицы вложенным циклом, а спустя 5 мин., когда Вы застопили Web-сервис на той же машине, он будет применять hash join, потому что освободилась память, в которой можно построить хэш-таблицу. Хотя, если у Вас Desktop Edition, то там, по-моему, все эти прибамбасы не поддерживаются. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.09.2001, 10:43 |
|
||
|
MSSQL2000: INNER JOIN vs. обычная запятая
|
|||
|---|---|---|---|
|
#18+
Ну насчет MIN я согласен, тем более если удельный вес подобных операций невысок, то не стоит усложнять оптимизатор. Хотя, все-таки, поиск минимума по Б-дереву, это уж такая классика... Ну да ладно, это меня особо не напрягло. А вот JOIN меня удивил. Я запускал запрос в однопользовательской среде, никого вокруг, никакого WEB и прочего. Для чистоты эксперимента я даже сервер перезапускал. И не перезапускал тоже. Разница есть! А если на клетке с тигром написано "заяц" - не верь глазам своим. А может правда заяц? ... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.09.2001, 11:23 |
|
||
|
MSSQL2000: INNER JOIN vs. обычная запятая
|
|||
|---|---|---|---|
|
#18+
Рассудите здраво: план (= алгоритм) один и тот же. С чего может меняться время выполнения? Значит, не все факторы учтены. У Вас for (int i = 0; i++; i < N) тоже плавает? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.09.2001, 12:55 |
|
||
|
|

start [/forum/topic.php?fid=46&msg=32013457&tid=1825629]: |
0ms |
get settings: |
7ms |
get forum list: |
10ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
72ms |
get topic data: |
7ms |
get forum data: |
2ms |
get page messages: |
34ms |
get tp. blocked users: |
1ms |
| others: | 252ms |
| total: | 391ms |

| 0 / 0 |
