Гость
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Не учитывается предикат во вью при использовании оконных функций / 25 сообщений из 26, страница 1 из 2
05.12.2020, 18:33
    #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
05.12.2020, 18:34
    #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
05.12.2020, 19:22
    #40024906
alexeyvg
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не учитывается предикат во вью при использовании оконных функций
osipen
Наверняка есть научное объяснение этому поведению?
Да, есть, и очень простое объяснение.
Вы будете смеяться, но это два разных запроса, которые выдают разный результат.
И вполне естественно, что для получения разных результатов нужен разный план (результат в запросе со вьюхой не получить без сканирования таблицы)
...
Рейтинг: 0 / 0
05.12.2020, 19:23
    #40024907
aleks222
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не учитывается предикат во вью при использовании оконных функций
Ты сам то видишь разницу в результатах запроса?
Глазки протри.
...
Рейтинг: 0 / 0
05.12.2020, 19:38
    #40024912
alexeyvg
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не учитывается предикат во вью при использовании оконных функций
aleks222
Ты сам то видишь разницу в результатах запроса?
Глазки протри.
Это вы кому нахамили, мне, или топикстартеру?
...
Рейтинг: 0 / 0
05.12.2020, 20:03
    #40024917
invm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не учитывается предикат во вью при использовании оконных функций
osipen,

Потому что, грубо говоря, ранжирующие и оконные функции вычисляются на результирующем наборе.
Поэтому сначала row_number в представлении со всеми вытекающими, а потом уже фильтр по id = 1
...
Рейтинг: 0 / 0
05.12.2020, 20:05
    #40024918
НеофитSQL
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не учитывается предикат во вью при использовании оконных функций
На мой взгляд, запросы эквивалентны. Если один исполняется менее эффективно, это наверное недочёт оптимизатора.
...
Рейтинг: 0 / 0
06.12.2020, 00:25
    #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
06.12.2020, 01:37
    #40024991
Focha
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не учитывается предикат во вью при использовании оконных функций
alexeyvg
osipen
Наверняка есть научное объяснение этому поведению?
Да, есть, и очень простое объяснение.
Вы будете смеяться, но это два разных запроса, которые выдают разный результат.
И вполне естественно, что для получения разных результатов нужен разный план (результат в запросе со вьюхой не получить без сканирования таблицы)

Я вообще не понимаю, как у человека появляются такие вопросы.
...
Рейтинг: 0 / 0
06.12.2020, 10:20
    #40025004
alexeyvg
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не учитывается предикат во вью при использовании оконных функций
НеофитSQL
На мой взгляд, запросы эквивалентны. Если один исполняется менее эффективно, это наверное недочёт оптимизатора.
Ещё раз - разные запросы. Запрос из вьюхи нельзя выполнять без скана. Вам же надо посчитать все записи, без фильтра , отранжировать, о каком индексе идёт речь?
Дело не во вьюхе, а в семантике запроса. Если без вьюхи сделать то же самое (Владислав Колосов привёл пример), то план будет такой же, со сканом вместо индекс сик.
Focha
Я вообще не понимаю, как у человека появляются такие вопросы.
Ну, семантику запроса можно сразу не разглядеть...
Похоже на задачу на собеседовании :-) Всяко лучше, чем про люки и продажу бензина :-)
...
Рейтинг: 0 / 0
06.12.2020, 18:33
    #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
06.12.2020, 22:19
    #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
07.12.2020, 04:47
    #40025128
Сон Веры Павловны
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не учитывается предикат во вью при использовании оконных функций
Вот здесь SomewhereSomehow всё по полочкам разложил. В т.ч. про проталкивание предикатов. В оракле, кстати, в запросах с оконными функциями примерно та же самая картина - в случаях, подобных вышеописанному, оптимизатор протолкнуть предикаты не может.
...
Рейтинг: 0 / 0
07.12.2020, 08:41
    #40025140
andreymx
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не учитывается предикат во вью при использовании оконных функций
Сон Веры Павловны
Вот здесь SomewhereSomehow всё по полочкам разложил. В т.ч. про проталкивание предикатов. В оракле, кстати, в запросах с оконными функциями примерно та же самая картина - в случаях, подобных вышеописанному, оптимизатор протолкнуть предикаты не может.
наверное, и не должен
...
Рейтинг: 0 / 0
07.12.2020, 13:17
    #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
07.12.2020, 13:36
    #40025228
andreymx
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не учитывается предикат во вью при использовании оконных функций
НеофитSQL,

по-моему, в общем случае это извращение
вставлять в представление distinct, union без all, аналитику, сортировку (в оракле можно)
...
Рейтинг: 0 / 0
07.12.2020, 13:53
    #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
07.12.2020, 13:59
    #40025240
НеофитSQL
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не учитывается предикат во вью при использовании оконных функций
andreymx
НеофитSQL,

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


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

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

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

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

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

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

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

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


Через Топ 100%? Так вроде ж не работает?
...
Рейтинг: 0 / 0
07.12.2020, 19:05
    #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
07.12.2020, 19:51
    #40025403
НеофитSQL
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Не учитывается предикат во вью при использовании оконных функций
Щукина Анна,

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

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


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