Работает ли оптимизатор плана запросов с объединенными / отфильтрованными табличными функциями? - PullRequest
2 голосов
/ 22 ноября 2008

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

Я использую тезисы внутри больших запросов в качестве объединенных вычислений, и мне интересно, хорошо ли работает оптимизатор плана запросов с ними при любых условиях или мне лучше использовать такие вычисления в моих больших запросах.

  1. Оптимизирует ли оптимизатор плана запросов табличные функции, если это сделать смысл?
  2. Если это не так, что ты рекомендую избегать дублирования кода это произойдет вручную разве их?
  3. Если да, то как вы идентифицируете это по казни планировать?

пример кода:

create table dbo.customers (
    [key] uniqueidentifier
    , constraint pk_dbo_customers
        primary key ([key])
)
go

/* assume large amount of data */
create table dbo.point_of_sales (
    [key] uniqueidentifier
    , customer_key uniqueidentifier
    , constraint pk_dbo_point_of_sales
        primary key ([key])
)
go

create table dbo.product_ranges (
    [key] uniqueidentifier
    , constraint pk_dbo_product_ranges
        primary key ([key])
)
go

create table dbo.products (
    [key] uniqueidentifier
    , product_range_key uniqueidentifier
    , release_date datetime
    , constraint pk_dbo_products 
        primary key ([key])
    , constraint fk_dbo_products_product_range_key 
        foreign key (product_range_key) 
        references dbo.product_ranges ([key])
)
go

.

/* assume large amount of data */
create table dbo.sales_history (
    [key] uniqueidentifier
    , product_key uniqueidentifier
    , point_of_sale_key uniqueidentifier
    , accounting_date datetime
    , amount money
    , quantity int
    , constraint pk_dbo_sales_history
        primary key ([key])
    , constraint fk_dbo_sales_history_product_key
        foreign key (product_key)
        references dbo.products ([key])
    , constraint fk_dbo_sales_history_point_of_sale_key
        foreign key (point_of_sale_key)
        references dbo.point_of_sales ([key])
)
go

create function dbo.f_sales_history_..snip.._date_range
(
    @accountingdatelowerbound datetime,
         @accountingdateupperbound datetime
)
returns table as
return (
    select
                  pos.customer_key
        , sh.product_key
        , sum(sh.amount) amount
        , sum(sh.quantity) quantity
    from 
        dbo.point_of_sales pos
        inner join dbo.sales_history sh 
            on sh.point_of_sale_key = pos.[key]
    where
                  sh.accounting_date between 
                      @accountingdatelowerbound and 
                      @accountingdateupperbound
    group by
                  pos.customer_key
                  , sh.product_key
)
go

-- TODO: insert some data

-- this is a table containing a selection of product ranges
declare @selectedproductranges table([key] uniqueidentifier)

-- this is a table containing a selection of customers
declare @selectedcustomers table([key] uniqueidentifier)

declare @low datetime
    , @up datetime

-- TODO: set top query parameters

.

select
         saleshistory.customer_key
         , saleshistory.product_key
         , saleshistory.amount
         , saleshistory.quantity
from
         dbo.products p
         inner join @selectedproductranges productrangeselection 
             on p.product_range_key = productrangeselection.[key]
         inner join @selectedcustomers customerselection on 1 = 1
         inner join 
         dbo.f_sales_history_..snip.._date_range(@low, @up) saleshistory
             on saleshistory.product_key = p.[key]
             and saleshistory.customer_key = customerselection.[key]

Надеюсь, образец имеет смысл.

Большое спасибо за вашу помощь!

Ответы [ 2 ]

5 голосов
/ 22 ноября 2008

В данном случае это «встроенная табличная функция» Оптимизатор просто расширяет (снимает) его, если он полезен (или просмотр).

Если функция обрабатывается внешним запросом как «черный ящик», самый быстрый способ - сравнить IO, показанный в SSMS, с IO в профилировщике. Profler фиксирует IO «черного ящика», которого нет в SSMS.

Сообщение в блоге Адама Механика (его книга в моем ящике на работе)

3 голосов
/ 22 ноября 2008

1) Да, используя ваш синтаксис, это так. Если бы вы использовали UDF, который возвращал таблицу с условной логикой, это не так.

3) Оптимизатор не будет указывать, какую часть вашего запроса он оптимизирует, потому что он может счесть целесообразным объединить фрагменты плана с вашей функцией или оптимизировать отдельные части.

...