문제

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]

샘플이 의미가 있기를 바랍니다.

도와 주셔서 감사합니다!

도움이 되었습니까?

해결책

이 경우, "인라인 테이블 값 함수"입니다. 최적화기는 유용한 경우 (또는보기) 단순히 확장 (Unnests)입니다.

기능이 외부 쿼리에 의해 "블랙 박스"로 취급되는 경우, 가장 빠른 방법은 프로파일 러에서 SSMS 대 IO에 표시된 IO를 비교하는 것입니다. Profler는 SSMS가하지 않는 "블랙 박스"IO를 캡처합니다.

Adam Mechanic의 블로그 게시물 (그의 책은 직장에서 내 서랍에 있습니다)

다른 팁

1) 예, 구문을 사용하여 그렇습니다. 조건부 논리가있는 테이블을 반환 한 UDF를 사용한 경우에는 그렇지 않습니다.

3) Optimizer는 계획의 덩어리를 기능과 결합하거나 비트를 최적화하는 데 적합 할 수 있기 때문에 최적화하는 쿼리의 일부를 지적하지 않습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top