Как уменьшить логическое чтение при получении результата от просмотра? - PullRequest
0 голосов
/ 12 октября 2019

У меня есть представление, в котором я упомяну его код ниже, когда я фильтрую весь код, я получаю правильное логическое чтение, но когда я фильтрую представление, логическое чтение увеличивается настолько сильно!

Вместо этого я использовал подзапросcte, я сделал так много изменений в своем коде, но не смог получить правильный результат

Это мой код просмотра:

create view att.view_notRule
as

with timeline
as
(
    select person,location,dateTime,d_base
    from att.view_pD1

    union all

    select person,location,dateTime_in,d_base
    from att.view_rule

    union all

    select person,location,dateTime_out,d_base
    from att.view_rule
),
timelineRanking
as
(
    select person,location,row_number() over (partition by person,location,d_base order by dateTime) rank,dateTime,d_base
    from timeline
)

select x.person,x.location,x.dateTime dateTime_start,y.dateTime dateTime_end,x.d_base
from timelineRanking x
inner join timelineRanking y on x.person=y.person and x.location=y.location and x.d_base=y.d_base
where x.rank+1=y.rank and x.rank%2=1

, когда я выполняю этот запрос, я сталкиваюсь со многимилогические чтения:

select *
from att.view_notRule
where person='B18FE132-2779-4E0D-A776-4BD27E7EEB7C'

Но когда я фильтрую человека внутри кода, я получаю правильное логическое чтение

Мне нужно выполнить это:

select *
from att.view_notRule
where person='B18FE132-2779-4E0D-A776-4BD27E7EEB7C'

Нополучать правильные логические чтения

Ответы [ 2 ]

1 голос
/ 12 октября 2019

Когда вы запрашиваете из представления, которое не может распространять предикаты, до базовых таблиц (что иногда связано с дизайном представления, а иногда из-за ограничений в оптимизаторе запросов), полезно заменить представление. с встроенной табличной функцией, которая похожа на параметризованное представление.

например:

create or alter function att.view_notRule(@person varchar(200)) returns table 
as return

with timeline
as
(
    select person,location,dateTime,d_base
    from att.view_pD1
    where person = @person 

    union all

    select person,location,dateTime_in,d_base
    from att.view_rule
    where person = @person 

    union all

    select person,location,dateTime_out,d_base
    from att.view_rule
    where person = @person 

),
timelineRanking
as
(
    select person,location,row_number() over (partition by person,location,d_base order by dateTime) rank,dateTime,d_base
    from timeline
)

select x.person,x.location,x.dateTime dateTime_start,y.dateTime dateTime_end,x.d_base
from timelineRanking x
inner join timelineRanking y on x.person=y.person and x.location=y.location and x.d_base=y.d_base
where x.rank+1=y.rank and x.rank%2=1

Тогда, если вам нужно запустить представление для нескольких людей, вы можетесделать это с помощью CROSS APPLY. Но для вашего

0 голосов
/ 13 октября 2019

Если логическое чтение - это проблема, я обычно начинаю фильтровать базовые таблицы (как упоминал Дэвид Браун). В вашем случае он будет работать как функция вместо представления, применяя предложение WHERE внутри CTE.

Кроме того, я бы рекомендовал избегать самостоятельного объединения, вместо этого используйте функцию LEAD(), ниже приведен тот же пример, с которого вы можете начать:

Declare @PersonID varchar(20) = 'YourData';

with timeline
as
(
    select person, location, dateTime, d_base
    from att.view_pD1
    where   person = @PersonID

    union all

    select  person, location, dateTime_in, d_base
    from    att.view_rule
    where   person = @PersonID

    union all

    select person, location, dateTime_out, d_base
    from att.view_rule
    where   person = @PersonID
)

select  person,
        location, 
        d_base,
        dateTime as StartTime,
        LEAD(dateTime) over (partition by person, location, d_base order by dateTime) EndTime
from    timeline
go

или Чтобы получить крайнюю дату начала и окончания, вы можете начать со следующего:

Declare @PersonID varchar(20) = 'YourData';

select  m.person, 
        m.location, 
        m.d_base, 
        s.datetime as StartTime, 
        e.datetime as EndTime
from att.<viewMasterData> as M

    LEFT JOIN 
    (select person, location, datetime, d_base,
            ROW_NUMBER () OVER (Partition by person, location, d_base order by datetime) as StartRN
    from    att.view_rule
    where   person = @PersonID
    ) as s ON M.person = s.person and m.location = s.location and m.base = s.base

    LEFT JOIN 
    (select person, location, datetime, d_base,
            ROW_NUMBER () OVER (Partition by person, location, d_base order by datetime desc) as EndRN
    from    att.view_rule
    where   person = @PersonID
    ) as e ON M.person = e.person and m.location = e.location and m.base = e.base
where s.StartRN = 1 and e.EndRN = 1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...