|
Cross apply/ Outer apply VS Joins
|
|||
---|---|---|---|
#18+
Прочитал довольно много информации не особо всё равно могу понять преимуществ и разницы в этих вещах. Да, в apply можно коррелирующий запрос , ок. Вот вроде бы всё понятно написано НО. Принципиальная разница в чем? Join берёт каждую строку из левой таблицы и сравнивает её с каждой строкой правой, выводит все данные с левой таблички и заNULLивает любые несовпадения с правой таблицы. Но ведь apply тоже самое делает, оценивает записи и если нет совпадения пишет NULL . Резалт сет одинаковый но в Apply появляется Compute Scalar оператор. Никак не могу понять разницы и преимущества того или иного . Пример: The first query in Script #3 selects data from Department table and uses an OUTER APPLY to evaluate the Employee table for each record of the Department table. For those rows for which there is not a match in the Employee table, those rows contain NULL values as you can see in case of row 5 and 6 below. The second query simply uses a LEFT OUTER JOIN between the Department table and the Employee table. As expected the query returns all rows from Department table, even for those rows for which there is no match in the Employee table. Even though the above two queries return the same information, the execution plan is a bit different. Although cost wise there is not much difference, the query with the OUTER APPLY uses a Compute Scalar operator (with estimated operator cost of 0.0000103 or around 0%) before the Nested Loops operator to evaluate and produce the columns of the Employee table. --Script #3 - OUTER APPLY and LEFT OUTER JOIN SELECT * FROM Department D OUTER APPLY ( SELECT * FROM Employee E WHERE E.DepartmentID = D.DepartmentID ) A GO SELECT * FROM Department D LEFT OUTER JOIN Employee E ON D.DepartmentID = E.DepartmentID GO ... |
|||
:
Нравится:
Не нравится:
|
|||
22.06.2019, 14:15 |
|
Cross apply/ Outer apply VS Joins
|
|||
---|---|---|---|
#18+
Попробуйте табличную функцию поджоинить с передачей ей параметров. ... |
|||
:
Нравится:
Не нравится:
|
|||
22.06.2019, 14:54 |
|
Cross apply/ Outer apply VS Joins
|
|||
---|---|---|---|
#18+
А так простым JOINом напишете? Код: sql 1. 2. 3.
Я, конечно, понимаю, что с применением ROW_NUMBER()OVER() вы это сделаете. ... |
|||
:
Нравится:
Не нравится:
|
|||
22.06.2019, 14:57 |
|
Cross apply/ Outer apply VS Joins
|
|||
---|---|---|---|
#18+
iapА так простым JOINом напишете? Код: sql 1. 2. 3.
Я, конечно, понимаю, что с применением ROW_NUMBER()OVER() вы это сделаете. Канешно для полноты щастья нужен идентификатор строки, но что-то вроде Код: sql 1. 2. 3.
... |
|||
:
Нравится:
Не нравится:
|
|||
22.06.2019, 15:09 |
|
Cross apply/ Outer apply VS Joins
|
|||
---|---|---|---|
#18+
iapА так простым JOINом напишете? Код: sql 1. 2. 3.
Я, конечно, понимаю, что с применением ROW_NUMBER()OVER() вы это сделаете. я бы был очень признателен если бы вы смогли кратко пояснить разницу на словах ... |
|||
:
Нравится:
Не нравится:
|
|||
22.06.2019, 15:10 |
|
Cross apply/ Outer apply VS Joins
|
|||
---|---|---|---|
#18+
Гавриленко Сергей АлексеевичПопробуйте табличную функцию поджоинить с передачей ей параметров. разница в коррелирующих подзапросах и табличных функциях? ... |
|||
:
Нравится:
Не нравится:
|
|||
22.06.2019, 15:11 |
|
Cross apply/ Outer apply VS Joins
|
|||
---|---|---|---|
#18+
RitzuГавриленко Сергей АлексеевичПопробуйте табличную функцию поджоинить с передачей ей параметров. разница в коррелирующих подзапросах и табличных функциях?А вам мало? ... |
|||
:
Нравится:
Не нравится:
|
|||
22.06.2019, 15:48 |
|
Cross apply/ Outer apply VS Joins
|
|||
---|---|---|---|
#18+
Гавриленко Сергей АлексеевичRitzuпропущено... разница в коррелирующих подзапросах и табличных функциях?А вам мало? нет, мне просто нужно знать разницу между apply и joins. и желательно на где лучше использовать то или другое при равных условиях ... |
|||
:
Нравится:
Не нравится:
|
|||
22.06.2019, 16:02 |
|
Cross apply/ Outer apply VS Joins
|
|||
---|---|---|---|
#18+
Ritzuнет, мне просто нужно знать разницу между apply и joins. и желательно на где лучше использовать то или другое при равных условияхНужно использовать то, что дает план/производительность лучше в конкретном случае. А если одинаково, то пишите, что нравится, короче, феншуйнее -- сугубо по вашим предпочтениям. ... |
|||
:
Нравится:
Не нравится:
|
|||
22.06.2019, 16:18 |
|
Cross apply/ Outer apply VS Joins
|
|||
---|---|---|---|
#18+
Ritzu ... мне просто нужно знать разницу между apply и joins Apply дает возможность использовать в запросе "анонимную" табличную функцию. Джойны тут вообще не при делах - у них другое предназначение. ... |
|||
:
Нравится:
Не нравится:
|
|||
22.06.2019, 16:43 |
|
Cross apply/ Outer apply VS Joins
|
|||
---|---|---|---|
#18+
RitzuГавриленко Сергей Алексеевичпропущено... А вам мало? нет, мне просто нужно знать разницу между apply и joins. и желательно на где лучше использовать то или другое при равных условиях А кто Вам сказал, что разница есть? join - это сокращенный вариант apply. join соединяет набор записей, стоящий слева, с набором записей, стоящим справа в общий резалтсет, в случае, если предикат в on становится истинным. apply присоединяет к левому набору записей, к каждой его записи, набор записей образующийся "внутри" выражения apply, и тоже образует общий резалтсет. cross apply и inner join, имеется ввиду. Концептуально, это одно и то же, и вариант с join - это упрощённый и специализированный вариант apply. Собственно, из-за того, что join - это упрощенный и специализированный вариант, в котором обычно функция, согласно которой каждой записи левого набора сопоставляется каждая запись правого - очень простая и "вывернутая наружу потрохами", join работает очень быстро. Для нее энжин знает кучу трюков, позволяющих сократить трудоемкость формирования итогового резалтсета. А про apply в общем случае, оптимизатору - мало что известно, и жульничать ему гораздо труднее. В общем случае. Поэтому, обычно, априорно будет быстрее запрос, написанный в варианте join, чем apply. Например, на больших выборках, выгоднее, см. вышеописанный пример с cross apply (select top (1) * from ... where a.id=b.id order by ...), переписать его через join и оконные функции. Т.е. сформировать весь набор записей, которые подпадают под условие соединения, пометить каждую запись через Row_Number(), в соответствии с такими же критериями сортировки, а потом отобрать внешним подзапросом все записи с Row_Number = 1. Но, с учётом того, что оптимизатор очень и очень умный, всё это так... писями по воде виляно. Нужно взять план и посмотреть. ... |
|||
:
Нравится:
Не нравится:
|
|||
22.06.2019, 17:01 |
|
Cross apply/ Outer apply VS Joins
|
|||
---|---|---|---|
#18+
Ritzuя бы был очень признателен если бы вы смогли кратко пояснить разницу на словах Поясняю. Подавляющему большинству программиЗдов современности коррелированный подзапрос не по мозгу. Вот и сделали попроще. ... |
|||
:
Нравится:
Не нравится:
|
|||
22.06.2019, 18:00 |
|
Cross apply/ Outer apply VS Joins
|
|||
---|---|---|---|
#18+
uaggsterRitzuпропущено... нет, мне просто нужно знать разницу между apply и joins. и желательно на где лучше использовать то или другое при равных условиях А кто Вам сказал, что разница есть? join - это сокращенный вариант apply. join соединяет набор записей, стоящий слева, с набором записей, стоящим справа в общий резалтсет, в случае, если предикат в on становится истинным. apply присоединяет к левому набору записей, к каждой его записи, набор записей образующийся "внутри" выражения apply, и тоже образует общий резалтсет. cross apply и inner join, имеется ввиду. Концептуально, это одно и то же, и вариант с join - это упрощённый и специализированный вариант apply. Собственно, из-за того, что join - это упрощенный и специализированный вариант, в котором обычно функция, согласно которой каждой записи левого набора сопоставляется каждая запись правого - очень простая и "вывернутая наружу потрохами", join работает очень быстро. Для нее энжин знает кучу трюков, позволяющих сократить трудоемкость формирования итогового резалтсета. А про apply в общем случае, оптимизатору - мало что известно, и жульничать ему гораздо труднее. В общем случае. Поэтому, обычно, априорно будет быстрее запрос, написанный в варианте join, чем apply. Например, на больших выборках, выгоднее, см. вышеописанный пример с cross apply (select top (1) * from ... where a.id=b.id order by ...), переписать его через join и оконные функции. Т.е. сформировать весь набор записей, которые подпадают под условие соединения, пометить каждую запись через Row_Number(), в соответствии с такими же критериями сортировки, а потом отобрать внешним подзапросом все записи с Row_Number = 1. Но, с учётом того, что оптимизатор очень и очень умный, всё это так... писями по воде виляно. Нужно взять план и посмотреть. Ну вот супер, спасибо , всё как и хотел узнать! ... |
|||
:
Нравится:
Не нравится:
|
|||
22.06.2019, 18:27 |
|
Cross apply/ Outer apply VS Joins
|
|||
---|---|---|---|
#18+
uaggsterКонцептуально, это одно и то же, и вариант с join - это упрощённый и специализированный вариант apply. RitzuНу вот супер, спасибо , всё как и хотел узнать! Когда loop join от apply начнет периодически раздражать, придет понимание, что это не всегда одно и то же. UPD: а, да, что-то мне сходу не соображается головой, как с apply сделать full join. ... |
|||
:
Нравится:
Не нравится:
|
|||
22.06.2019, 19:20 |
|
Cross apply/ Outer apply VS Joins
|
|||
---|---|---|---|
#18+
Гавриленко Сергей АлексеевичuaggsterКонцептуально, это одно и то же, и вариант с join - это упрощённый и специализированный вариант apply. RitzuНу вот супер, спасибо , всё как и хотел узнать! Когда loop join от apply начнет периодически раздражать, придет понимание, что это не всегда одно и то же. UPD: а, да, что-то мне сходу не соображается головой, как с apply сделать full join. Гы. Хороший вопрос. Хочется, конечно, сказать, что как раньше, когда не было full join, как union из left и right join, но тут ведь какая проблема... это возможно только в том случае, когда корреллируемая выборка существует сама по себе, т.с. Когда loop join от apply начнет периодически раздражать А, строго говоря, loop join - это единственный всегда возможный вариант соединения. А всё остальное - как раз трюки, которые возможны не всегда, не везде и не для всех условий. Собственно, о чем я и говорил. ... |
|||
:
Нравится:
Не нравится:
|
|||
22.06.2019, 20:00 |
|
Cross apply/ Outer apply VS Joins
|
|||
---|---|---|---|
#18+
uaggsterjoin - это сокращенный вариант apply. Там, где join эквивалентен apply, нет никакого смысла писать apply. НО! есть ситуации, где нельзя сделать join, а возможен лишь apply. Например, выбрать запись по TOP 1 или сделать COALESCE по нескольким полям Код: sql 1. 2. 3. 4. 5. 6. 7.
Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18.
Ну и еще его используют для развертывания табличных функций, НАПРИМЕР ПРИ ПАРЗИНГЕ xml Код: sql 1. 2. 3. 4. 5. 6.
... |
|||
:
Нравится:
Не нравится:
|
|||
24.06.2019, 13:38 |
|
Cross apply/ Outer apply VS Joins
|
|||
---|---|---|---|
#18+
a_voroninНО! есть ситуации, где нельзя сделать join, а возможен лишь apply.Если не знаете как написать через join, то это вовсе не означает невозможность join'а Особо показательно будет в вашем первом примере при невозможности задействовать подходящий индекс. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.06.2019, 14:10 |
|
Cross apply/ Outer apply VS Joins
|
|||
---|---|---|---|
#18+
invmОсобо показательно Вот скажите мне, господин профессор джойнописания. Если нужно выбрать по 1 записи из А, а в В И С куча записей присоединяется по условию , то как вы запишите следующее: SELECT A.*, B.*, C.* FROM A OUTER APPPLY ( SELECT TOP 1 FROM B WHERE A.A_Id = B.A_Id ORDER BY X ) B OUTER APPPLY ( SELECT TOP 1 FROM С WHERE A.A_Id = С.A_Id ORDER BY X ) С ... |
|||
:
Нравится:
Не нравится:
|
|||
24.06.2019, 15:04 |
|
Cross apply/ Outer apply VS Joins
|
|||
---|---|---|---|
#18+
a_voroninто как вы запишите следующее: SELECT A.*, B.*, C.* FROM A OUTER APPPLY ( SELECT TOP 1 FROM B WHERE A.A_Id = B.A_Id ORDER BY X ) B OUTER APPPLY ( SELECT TOP 1 FROM С WHERE A.A_Id = С.A_Id ORDER BY X ) С Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11.
... |
|||
:
Нравится:
Не нравится:
|
|||
24.06.2019, 15:15 |
|
Cross apply/ Outer apply VS Joins
|
|||
---|---|---|---|
#18+
invma_voroninто как вы запишите следующее: SELECT A.*, B.*, C.* FROM A OUTER APPPLY ( SELECT TOP 1 FROM B WHERE A.A_Id = B.A_Id ORDER BY X ) B OUTER APPPLY ( SELECT TOP 1 FROM С WHERE A.A_Id = С.A_Id ORDER BY X ) С Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11.
Хорошо, такой вариант имеет право на существование. Но вопрос, будет ли он оптимальней по производительности, при наличии индексов? Например, если все таблицы колумнсторы. Ведь в вашем случае, нужно вычислять rownumber для всех связанных записей. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.06.2019, 15:28 |
|
Cross apply/ Outer apply VS Joins
|
|||
---|---|---|---|
#18+
a_voronininvmпропущено... Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11.
Хорошо, такой вариант имеет право на существование. Но вопрос, будет ли он оптимальней по производительности, при наличии индексов? Например, если все таблицы колумнсторы. Ведь в вашем случае, нужно вычислять rownumber для всех связанных записей. а apply будет вычислять для кадждой записи ваш топ 1, так себе оптимальность ... |
|||
:
Нравится:
Не нравится:
|
|||
24.06.2019, 15:30 |
|
Cross apply/ Outer apply VS Joins
|
|||
---|---|---|---|
#18+
TaPaKа apply будет вычислять для кадждой записи ваш топ 1, так себе оптимальность при наличии индексов (a_id, X) - вполне ... |
|||
:
Нравится:
Не нравится:
|
|||
24.06.2019, 15:46 |
|
Cross apply/ Outer apply VS Joins
|
|||
---|---|---|---|
#18+
a_voroninНо вопрос, будет ли он оптимальней по производительности, при наличии индексов?Я, по-вашему, просто так упомянул про невозможность индекса? Изучайте Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87.
... |
|||
:
Нравится:
Не нравится:
|
|||
24.06.2019, 15:50 |
|
Cross apply/ Outer apply VS Joins
|
|||
---|---|---|---|
#18+
Сколько бы не читал на форума о пользе Apply. Обычно дополняют "фразой, а так он может" и добавляют агрегированную таблицу или top несколько строк. Да простым Join так не сделать но с подзапросом (получается код на строчку - две длинее) сделать и все равно выполняется несравнимо быстрее чем чере apply: Вот примеры (с таблицами с миллионами записей), а с outer apply ещё хуже и любой пример который на сайтах показан для apply пробую он работает всегда медленнее чем черз joins и подзапросы Вариант 1 (5 сек результат 493000) Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12.
Вариант 2 (43 мин и только 214 записей показалось из 493000 - устал ждать) Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11.
Вариант 3 (результаты близкие к варианту 2) Код: sql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11.
... |
|||
:
Нравится:
Не нравится:
|
|||
10.07.2020, 21:36 |
|
|
start [/forum/topic.php?fid=46&msg=39829465&tid=1685887]: |
0ms |
get settings: |
10ms |
get forum list: |
11ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
27ms |
get topic data: |
11ms |
get forum data: |
3ms |
get page messages: |
59ms |
get tp. blocked users: |
1ms |
others: | 276ms |
total: | 404ms |
0 / 0 |