powered by simpleCommunicator - 2.0.52     © 2025 Programmizd 02
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Не учитывается предикат во вью при использовании оконных функций
25 сообщений из 26, страница 1 из 2
Не учитывается предикат во вью при использовании оконных функций
    #40024893
osipen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день!

Почему в обычном запросе используется индекс, а если тоже запрос во вью будет сканировать таблицу. Если не использовать оконную функцию то все хорошо. Наверняка есть научное объяснение этому поведению? пример практического смысла не имеет, только отражает суть этого проведения. Смотрите план последних двух запросов.

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
drop table test1
create table test1 ( id int )
create clustered index ix_test1 on test1 (id)

declare @n int = 1

while @n<=1000
begin
	insert into test1
	select @n
	set @n=@n+1
end
go
create view view_test1 as
select row_number() over(order by id desc) rn,id from test1 
go


select * from view_test1 where id = 1
select row_number() over(order by id) rn,id from test1 where id = 1
...
Рейтинг: 0 / 0
Не учитывается предикат во вью при использовании оконных функций
    #40024894
osipen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
osipen
Добрый день!

Почему в обычном запросе используется индекс, а если тоже запрос во вью будет сканировать таблицу. Если не использовать оконную функцию то все хорошо. Наверняка есть научное объяснение этому поведению? пример практического смысла не имеет, только отражает суть этого проведения. Смотрите план последних двух запросов.

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
drop table test1
create table test1 ( id int )
create clustered index ix_test1 on test1 (id)

declare @n int = 1

while @n<=1000
begin
	insert into test1
	select @n
	set @n=@n+1
end
go
create view view_test1 as
select row_number() over(order by id desc) rn,id from test1 
go


select * from view_test1 where id = 1
select row_number() over(order by id desc) rn,id from test1 where id = 1

...
Рейтинг: 0 / 0
Не учитывается предикат во вью при использовании оконных функций
    #40024906
Фотография alexeyvg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
osipen
Наверняка есть научное объяснение этому поведению?
Да, есть, и очень простое объяснение.
Вы будете смеяться, но это два разных запроса, которые выдают разный результат.
И вполне естественно, что для получения разных результатов нужен разный план (результат в запросе со вьюхой не получить без сканирования таблицы)
...
Рейтинг: 0 / 0
Не учитывается предикат во вью при использовании оконных функций
    #40024907
aleks222
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ты сам то видишь разницу в результатах запроса?
Глазки протри.
...
Рейтинг: 0 / 0
Не учитывается предикат во вью при использовании оконных функций
    #40024912
Фотография alexeyvg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
aleks222
Ты сам то видишь разницу в результатах запроса?
Глазки протри.
Это вы кому нахамили, мне, или топикстартеру?
...
Рейтинг: 0 / 0
Не учитывается предикат во вью при использовании оконных функций
    #40024917
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
osipen,

Потому что, грубо говоря, ранжирующие и оконные функции вычисляются на результирующем наборе.
Поэтому сначала row_number в представлении со всеми вытекающими, а потом уже фильтр по id = 1
...
Рейтинг: 0 / 0
Не учитывается предикат во вью при использовании оконных функций
    #40024918
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
На мой взгляд, запросы эквивалентны. Если один исполняется менее эффективно, это наверное недочёт оптимизатора.
...
Рейтинг: 0 / 0
Не учитывается предикат во вью при использовании оконных функций
    #40024980
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НеофитSQL,

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

Код: sql
1.
2.
3.
select tbl1.rn, tbl1.id
from (select row_number() over(order by id desc) rn,id from dbo.test1) tbl1
where tbl1.id = 1



Мы явно его просим использовать фильтр после просмотра таблицы. Чтобы не попасть в такую ситуацию, можно использовать функцию, а не представление, т.е. параметризовать запрос.
...
Рейтинг: 0 / 0
Не учитывается предикат во вью при использовании оконных функций
    #40024991
Фотография Focha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alexeyvg
osipen
Наверняка есть научное объяснение этому поведению?
Да, есть, и очень простое объяснение.
Вы будете смеяться, но это два разных запроса, которые выдают разный результат.
И вполне естественно, что для получения разных результатов нужен разный план (результат в запросе со вьюхой не получить без сканирования таблицы)

Я вообще не понимаю, как у человека появляются такие вопросы.
...
Рейтинг: 0 / 0
Не учитывается предикат во вью при использовании оконных функций
    #40025004
Фотография alexeyvg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НеофитSQL
На мой взгляд, запросы эквивалентны. Если один исполняется менее эффективно, это наверное недочёт оптимизатора.
Ещё раз - разные запросы. Запрос из вьюхи нельзя выполнять без скана. Вам же надо посчитать все записи, без фильтра , отранжировать, о каком индексе идёт речь?
Дело не во вьюхе, а в семантике запроса. Если без вьюхи сделать то же самое (Владислав Колосов привёл пример), то план будет такой же, со сканом вместо индекс сик.
Focha
Я вообще не понимаю, как у человека появляются такие вопросы.
Ну, семантику запроса можно сразу не разглядеть...
Похоже на задачу на собеседовании :-) Всяко лучше, чем про люки и продажу бензина :-)
...
Рейтинг: 0 / 0
Не учитывается предикат во вью при использовании оконных функций
    #40025058
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Владислав Колосов
НеофитSQL,

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

Код: sql
1.
2.
3.
select tbl1.rn, tbl1.id
from (select row_number() over(order by id desc) rn,id from dbo.test1) tbl1
where tbl1.id = 1



Мы явно его просим использовать фильтр после просмотра таблицы. Чтобы не попасть в такую ситуацию, можно использовать функцию, а не представление, т.е. параметризовать запрос.


Я не у компа сейчас чтобы проверить этот конкретный случай, но из моего (не слишком богатого) опыта помню, что оптимизатор оракла в таких случаях раскрывает скобки и переносит условие во внутренний запрос, после чего внешний пропадает.
...
Рейтинг: 0 / 0
Не учитывается предикат во вью при использовании оконных функций
    #40025092
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Теперь у компа, проверил. Я ошибался в чтении этих запросов.

Используя пример из сообщения г. Колосова, я построил три запроса:
Код: sql
1.
2.
3.
select * from view_test1 where id = 5;
select row_number() over(order by id) rn,id from test1 where id = 5;
select * from (select row_number() over(order by id) rn,id from test1) where id = 5;



Они дают три разных результата. Почему это так, я пока не разбирался, на выходных надо отдыхать.
Если знающий народ не поможет с объяснением которое понятно новичкам,
я разберусь в понедельник и разложу по полочкам.
...
Рейтинг: 0 / 0
Не учитывается предикат во вью при использовании оконных функций
    #40025128
Сон Веры Павловны
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот здесь SomewhereSomehow всё по полочкам разложил. В т.ч. про проталкивание предикатов. В оракле, кстати, в запросах с оконными функциями примерно та же самая картина - в случаях, подобных вышеописанному, оптимизатор протолкнуть предикаты не может.
...
Рейтинг: 0 / 0
Не учитывается предикат во вью при использовании оконных функций
    #40025140
andreymx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сон Веры Павловны
Вот здесь SomewhereSomehow всё по полочкам разложил. В т.ч. про проталкивание предикатов. В оракле, кстати, в запросах с оконными функциями примерно та же самая картина - в случаях, подобных вышеописанному, оптимизатор протолкнуть предикаты не может.
наверное, и не должен
...
Рейтинг: 0 / 0
Не учитывается предикат во вью при использовании оконных функций
    #40025218
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
andreymx
Сон Веры Павловны
Вот здесь SomewhereSomehow всё по полочкам разложил. В т.ч. про проталкивание предикатов. В оракле, кстати, в запросах с оконными функциями примерно та же самая картина - в случаях, подобных вышеописанному, оптимизатор протолкнуть предикаты не может.
наверное, и не должен


Точно, не должен. Смысл разный.
Да, там все хорошо и подробно человек написал.

Я с утра посмотрел на ранее написанные три запроса, исправил опечатки, и понял следующее:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
select row_number() over(order by id desc) rn,id from test1 where id = 5;
-- этот запрос для уникальных id эквивалентен такому: select 1 rn, id from test1 where id = 5
-- потому что "where" учитывается до того, как считается select, и row_number по одной строке - 1

select * from view_test1 where id = 5;
select * from (select row_number() over(order by id desc) rn,id from test1) where id = 5;
-- эти два эквивалентны. Сначала строится таблица соответствий rn:id (FULL SCAN),
-- затем из этой временной таблицы выбирается строка



Все по правилам SQL, как и должно быть. Плюсую ссылку: здесь SomewhereSomehow всё по полочкам разложил.

Вопрос для виртуозов SQL - а можно ли как-то переписать эту вьюху, чтобы удалось протолкнуть в нее параметр,
чтобы действительно
Код: sql
1.
select * from view_test1 where id = 5

исполнялось как
Код: sql
1.
select row_number() over(order by id desc) rn,id from test1 where id = 5


?
...
Рейтинг: 0 / 0
Не учитывается предикат во вью при использовании оконных функций
    #40025228
andreymx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НеофитSQL,

по-моему, в общем случае это извращение
вставлять в представление distinct, union без all, аналитику, сортировку (в оракле можно)
...
Рейтинг: 0 / 0
Не учитывается предикат во вью при использовании оконных функций
    #40025237
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
andreymx,

Я раньше не задумывался про это, т.к. не использовал аналитику во вьюхах (и не знал о препятствиях в ее использовании).
Промер ТС открыл глаза, можно сказать.

При отсутствии аналитических функций, оптимизатор (в моем случае, Оракла) понимает что можно протолкнуть предикат, и план получается эффективным:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
drop table test1;
create table test1 ( id int );
create index ix_test1 on test1 (id);
create or replace view view_formula as 
select id, id*id square, id*id*id cube from test1; -- дает квадрат и куб числа

SQL> select * from view_formula where id=3;
                                     ID     SQUARE       CUBE
--------------------------------------- ---------- ----------
                                      3          9         27

SQL> explain plan for select * from view_formula where id=3;
Explained

SQL> select * FROM TABLE(DBMS_XPLAN.DISPLAY (FORMAT=>'ALL +OUTLINE'));
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
------------------------------------------------------------------
| Id  | Operation        | Name     | Rows  | Bytes | Cost (%CPU)|
------------------------------------------------------------------
|   0 | SELECT STATEMENT |          |     1 |     4 |     1   (0)|
|   1 |  INDEX RANGE SCAN| IX_TEST1 |     1 |     4 |     1   (0)|
------------------------------------------------------------------
...
Рейтинг: 0 / 0
Не учитывается предикат во вью при использовании оконных функций
    #40025240
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
andreymx
НеофитSQL,

по-моему, в общем случае это извращение
вставлять в представление distinct, union без all, аналитику, сортировку (в оракле можно)


С аналитикой понятно - эта тема иллюстрирует грабли.
С сортировкой тоже понятно - да и SQL запрещает/игнорирует сортировку в представлениях.

С distinct я вроде догадываюсь - эту операцию нужно применять в конце, а представление
по определению является подзапросом, поэтому может появиться второй distinct.

А какие проблемы с union в представлениях? Из-за промежуточной сортировки, которую можно избежать?
...
Рейтинг: 0 / 0
Не учитывается предикат во вью при использовании оконных функций
    #40025283
iap
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andreymx
НеофитSQL,

по-моему, в общем случае это извращение
вставлять в представление distinct, union без all, аналитику, сортировку (в оракле можно)
В MSSQL тоже можно, но нелегально
...
Рейтинг: 0 / 0
Не учитывается предикат во вью при использовании оконных функций
    #40025314
Фотография env
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НеофитSQL
А какие проблемы с union в представлениях?

НеофитSQL
С distinct я вроде догадываюсь

Осталось совместить.
...
Рейтинг: 0 / 0
Не учитывается предикат во вью при использовании оконных функций
    #40025319
Фотография env
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НеофитSQL,

Откройте для себя сайты типа dbfiddle для проверки гипотез по sql server. Примеры с планами из оракла в этой ветке не особо котируются.
...
Рейтинг: 0 / 0
Не учитывается предикат во вью при использовании оконных функций
    #40025379
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
iap
andreymx
НеофитSQL,

по-моему, в общем случае это извращение
вставлять в представление distinct, union без all, аналитику, сортировку (в оракле можно)
В MSSQL тоже можно, но нелегально


Через Топ 100%? Так вроде ж не работает?
...
Рейтинг: 0 / 0
Не учитывается предикат во вью при использовании оконных функций
    #40025390
Фотография Щукина Анна
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НеофитSQL
Через Топ 100%? Так вроде ж не работает?
Не работает с процентами - сделайте через количество строк. Просто число возьмите побольше. Охулиона вполне хватит. А если мало - возьмите дохулиард:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
with 
  t (rn) as 
    (
      select 1 union all
      select 2 union all
      select 3 union all
      select 4 union all
      select 5
    )
select *
  from (
         select top(9999999999999999) rn
           from t
          order by rn desc 
       ) v

  rn
-----
    5
    4
    3
    2
    1


Ссылка на fiddle
...
Рейтинг: 0 / 0
Не учитывается предикат во вью при использовании оконных функций
    #40025403
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Щукина Анна,

Прикольно, но насколько мне известно для работы такое непригодно.
Сортировка во внутреннем селекте официально не поддерживается кроме пары исключений.
...
Рейтинг: 0 / 0
Не учитывается предикат во вью при использовании оконных функций
    #40025405
Фотография Щукина Анна
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НеофитSQL
Щукина Анна,

Прикольно, но насколько мне известно для работы такое непригодно.
Сортировка во внутреннем селекте официально не поддерживается кроме пары исключений.
Само собой. Сортировку итоговой выборки обеспечивает и гарантирует только финальный явно указанный ORDER BY. Всё остальное - сортировка в подзапросе, сортировка от оконных функций, сортировка группировки (до эпохи изобретения HASH GROUP) - от лукавого и лишь видимость упорядоченности результата.
...
Рейтинг: 0 / 0
25 сообщений из 26, страница 1 из 2
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Не учитывается предикат во вью при использовании оконных функций
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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