Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
newid() по группе
|
|||
|---|---|---|---|
|
#18+
Необходимо каждой группе записей, определяемой полем gr присвоить свой newid(). Одним селектом, без промежуточных таблиц и без update-ов. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. Результат: grrowid1AB777FFA-609A-47B8-82F4-C7C60A41922016EE07AFF-14F7-4A3E-AEE7-19DC1738D6BA2EF3099D5-63EB-4BAC-BF6B-C2A242CEB13720EAFC893-0A4B-4B5A-8513-C667821E51E93134E2614-383D-4DB8-B06B-126846BA66DE К сожалению, здесь newid() отрабатывает на каждую запись результирующего набора. Нужный же результат выглядит так: grrowid1AB777FFA-609A-47B8-82F4-C7C60A4192201AB777FFA-609A-47B8-82F4-C7C60A4192202EF3099D5-63EB-4BAC-BF6B-C2A242CEB1372EF3099D5-63EB-4BAC-BF6B-C2A242CEB1373134E2614-383D-4DB8-B06B-126846BA66DE Код: plaintext ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.09.2008, 13:36 |
|
||
|
newid() по группе
|
|||
|---|---|---|---|
|
#18+
Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.09.2008, 13:43 |
|
||
|
newid() по группе
|
|||
|---|---|---|---|
|
#18+
Спасибо, так то оно конечно понятно, но к сожалению step_ksОдним селектом, без промежуточных таблиц и без update-ов. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.09.2008, 13:55 |
|
||
|
newid() по группе
|
|||
|---|---|---|---|
|
#18+
step_ksСпасибо, так то оно конечно понятно, но к сожалению step_ksОдним селектом, без промежуточных таблиц и без update-ов. Ну так что мешает добавить еще один подзапрос ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.09.2008, 13:57 |
|
||
|
newid() по группе
|
|||
|---|---|---|---|
|
#18+
GloryНу так что мешает добавить еще один подзапрос ? А вот тут мы попадаем на засаду... Не знаю, обсуждалось ли это где-то или нет, но, похоже, разработчики ввели CTE только как синтаксический сахар, унаследовав поведение derived tables, ибо: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. НО: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. и план показывает, когда сервер высчитывает NEWID(). И даже вот так... Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. Я понимаю, что функция недетерминированная, но зачем же так жесто перевирать мой запрос?! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.09.2008, 14:10 |
|
||
|
newid() по группе
|
|||
|---|---|---|---|
|
#18+
Ну, впринципе, и в доке об этом сказано: A common table expression (CTE) can be thought of as a temporary result set that is defined within the execution scope of a single SELECT, INSERT, UPDATE, DELETE, or CREATE VIEW statement. A CTE is similar to a derived table in that it is not stored as an object and lasts only for the duration of the query. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.09.2008, 14:18 |
|
||
|
newid() по группе
|
|||
|---|---|---|---|
|
#18+
Код: plaintext 1. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.09.2008, 14:31 |
|
||
|
newid() по группе
|
|||
|---|---|---|---|
|
#18+
Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.09.2008, 14:32 |
|
||
|
newid() по группе
|
|||
|---|---|---|---|
|
#18+
Glory Код: plaintext 1. Мдя... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.09.2008, 14:36 |
|
||
|
newid() по группе
|
|||
|---|---|---|---|
|
#18+
Glory Код: plaintext 1. Да, так max наводит порядок. Остается только гадать, а не "поумнеет" ли оптимизатор ли в один прекрасный день, начав его игнорировать. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.09.2008, 15:46 |
|
||
|
newid() по группе
|
|||
|---|---|---|---|
|
#18+
aleks2 Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. step_ks... и без update-ов. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.09.2008, 15:56 |
|
||
|
newid() по группе
|
|||
|---|---|---|---|
|
#18+
В продолжение старого разговора, дабы окончательно разобраться. Модифицируем пример из первого поста (используем 2 таблицы) и применим фокус с max по совету Glory: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. Результат остается нужным: grrowid15EC65C27-0785-4F9F-B42A-376451349DFB15EC65C27-0785-4F9F-B42A-376451349DFB2416C0C76-C9F1-4240-8B75-BB83FFFA339B2416C0C76-C9F1-4240-8B75-BB83FFFA339B Теперь даем оптимизатору знать, что у нас в @tt поле gr уникально (изменим определение @tt): Код: plaintext 1. и видим в плане, что max отброшен оптимизатором и newid() опять красуется в каждой строке результата: grrowid1F897E384-5011-4E17-B67C-457BD7F09FEB1CD9075FA-E3A6-4220-BE1A-355DEECCBC1020F25E3A6-7EF9-482D-8AB6-96EF37FA697724E3557D0-19AB-4A66-B89E-6396E7B8076F ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.03.2009, 13:12 |
|
||
|
newid() по группе
|
|||
|---|---|---|---|
|
#18+
step_ks Теперь даем оптимизатору знать, что у нас в @tt поле gr уникально (изменим определение @tt): Код: plaintext 1. А как вы при gr int primary key смогли добавить в таблицу insert @t (gr) select 1 insert @t (gr) select 1 insert @t (gr) select 2 insert @t (gr) select 2 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.03.2009, 13:16 |
|
||
|
newid() по группе
|
|||
|---|---|---|---|
|
#18+
Вот, что пишет по этому поводу Itzik Ben-Gan в своей статье (привожу статью полностью, так как для доступа к статье вроде нужен логин). Там же в статье есть ссылка на feedback Microsoft и их мнение на этот счет. Itzik Ben-Gan * [July 21, 2008] * Bug with NEWID Function * Return to Blog Index * By: Itzik Ben-Gan * Puzzled by T-SQL * InstantDoc #99807 * Web Exclusive from SQL Server Magazine This bug was first described by Thomas Glörfeld here . Related Microsoft Connect item can be found here . The bug has to do with invoking the NEWID function in a query defining a table expression (derived table, CTE, view, inline table-valued function), and then joining the table expression with another table. If the relationship between the table expression and the other table is 1:M, each row from the table expression can appear multiple times in the result of the join. The bug is that depending on the optimizer’s choices in terms of physical processing, SQL Server may end up evaluating the NEWID function once per each target row instead of once per each source row. This bug was tested on SQL Server versions 2000/SP4, 2005/SP2 and 2008/RC0. As an example, the following code creates the tables t1 and t2 that are related in a 1:M relationship, and a view that invokes the NEWID function per each row from t1: Код: plaintext 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. Consider the following query: Код: plaintext 1. 2. 3. You would expect the NEWID function to be evaluated per each source row; namely, per each row from t1. However, the function ends up being evaluated per each target row; namely, per each row in the result of the join. Here’s the output I got from one of the invocations of this query: a_idb_idnewid_val115232647A-0279-4F3C-9B7F-EA88B062A1AF11B87D2681-26C4-4B9A-8895-35EF138BC96422F69FE4D3-26AE-4642-9622-C8416C8FFC0C220ED5950C-12BF-4778-90A3-2AC55CD59AAD Instead of getting two distinct GUIDs (one per each source row from t1), you get four (one per each target row in the result of the join. I posted the bug on Microsoft Connect ( FeedbackID=350485 ), and after consideration, Microsoft decided to close the item and mark it as “Won’t Fix”. The reasoning behind the decision not to fix the bug is that in the vast majority of the cases, the optimization aspects that lead to the bug yield better performance without sacrificing the correctness of the query, and if you fall into one of the unusual cases where the correctness of the query is compromised, you can consider alternatives (e.g., physically materialize the data along with the NEWID values in a table). Here’s the response from Microsoft: “Closing the loop . . . I've discussed this question with the Dev team. And eventually we have decided not to change current behavior, for the following reasons: 1) The optimizer does not guarantee timing or number of executions of scalar functions. This is a long-established tenet. It's the fundamental 'leeway' that allows the optimizer enough freedom to gain significant improvements in query-plan execution. 2) This "once-per-row behavior" is not a new issue, although it's not widely discussed. We started to tweak its behavior back in the Yukon release. But it's quite hard to pin down precisely, in all cases, exactly what it means! For example, does it a apply to interim rows calculated 'on the way' to the final result? - in which case it clearly depends on the plan chosen. Or does it apply only to the rows that will eventually appear in the completed result? - there's a nasty recursion going on here, as I'm sure you'll agree! 3) As I mentioned earlier, we default to "optimize performance" - which is good for 99% of cases. The 1% of cases where it might change results are fairly easy to spot - side-effecting 'functions' such as NEWID - and easy to 'fix' (trading perf, as a consequence). This default to "optimize performance" again, is long-established, and accepted. (Yes, it's not the stance chosen by compilers for conventional programming languages, but so be it). So, our recommendations are: a) Avoid reliance on non-guaranteed timing and number-of-executions semantics. b) Avoid using NEWID() deep in table expressions. c) Use OPTION to force a particular behavior (trading perf) Hope this explanation helps clarify our reasons for closing this bug as "won't fix". Thanks, Jim” I wanted to point out the bug so that you would be aware of it and of the fact that a fix is not planned. If you need the NEWID function to be evaluated once per each source row, make sure you materialize the data in a table first. Cheers, BG ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.03.2009, 13:16 |
|
||
|
newid() по группе
|
|||
|---|---|---|---|
|
#18+
Glorystep_ks Теперь даем оптимизатору знать, что у нас в @tt поле gr уникально (изменим определение @tt): Код: plaintext 1. А как вы при gr int primary key смогли добавить в таблицу insert @t (gr) select 1 insert @t (gr) select 1 insert @t (gr) select 2 insert @t (gr) select 2 Там же инсерт тоже изменен: step_ks Код: plaintext 1. 2. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.03.2009, 13:20 |
|
||
|
newid() по группе
|
|||
|---|---|---|---|
|
#18+
step_ksGlorystep_ks Теперь даем оптимизатору знать, что у нас в @tt поле gr уникально (изменим определение @tt): Код: plaintext 1. А как вы при gr int primary key смогли добавить в таблицу insert @t (gr) select 1 insert @t (gr) select 1 insert @t (gr) select 2 insert @t (gr) select 2 Там же инсерт тоже изменен: step_ks Код: plaintext 1. 2. Да вы и задачу изменили А зачем тогда делать group by по полю primary key ? Типа давайте усложним работу оптимизатору ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.03.2009, 13:23 |
|
||
|
newid() по группе
|
|||
|---|---|---|---|
|
#18+
Glory Да вы и задачу изменили А зачем тогда делать group by по полю primary key ? Типа давайте усложним работу оптимизатору ? Да, изменил, и решения уже никакого не прошу (но было бы интересно, появись оно вдруг в новой задаче). Просто случайно попалась на глаза вышеприведенная статья и я решил проверить фокус с max в описанной в ней ситуации, о результатах чего и сообщаю. Возможно, будет кому-то полезно. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.03.2009, 13:31 |
|
||
|
newid() по группе
|
|||
|---|---|---|---|
|
#18+
Glory А зачем тогда делать group by по полю primary key ? Незачем, только для демонстрации на одном и том же селекте. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.03.2009, 13:34 |
|
||
|
newid() по группе
|
|||
|---|---|---|---|
|
#18+
step_ksНеобходимо каждой группе записей, определяемой полем gr присвоить свой newid(). Одним селектом, без промежуточных таблиц и без update-ов. Код: sql 1. 2. 3. 4. 5. 6. 7. 8. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.01.2018, 20:01 |
|
||
|
newid() по группе
|
|||
|---|---|---|---|
|
#18+
ATI.HeNRystep_ksНеобходимо каждой группе записей, определяемой полем gr присвоить свой newid(). Одним селектом, без промежуточных таблиц и без update-ов. Код: sql 1. 2. 3. 4. 5. 6. 7. 8. Т.е. версию в вопросе видел? "Microsoft SQL Server 2000 - 8.00.2039 (Intel X86) May 3 2005 23:18:38" ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.01.2018, 09:55 |
|
||
|
|

start [/forum/topic.php?fid=46&msg=35855814&tid=1690477]: |
0ms |
get settings: |
9ms |
get forum list: |
16ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
39ms |
get topic data: |
10ms |
get forum data: |
3ms |
get page messages: |
68ms |
get tp. blocked users: |
1ms |
| others: | 230ms |
| total: | 382ms |

| 0 / 0 |
