Question

Dans SQLSERVER 2005, j’utilise la fonction table-value comme moyen pratique d’agréger de manière arbitraire des données de sous-ensemble à partir d’une table volumineuse (plage de dates spécifiées ou paramètres similaires).

J'utilise ces thèses dans des requêtes plus volumineuses en tant que calculs joints et je me demande si l'optimiseur de plan de requête fonctionne bien avec elles dans toutes les conditions ou s'il est préférable que je supprime de tels calculs dans mes requêtes plus volumineuses.

  1. Désactive l'optimiseur de plan de requête fonctions à valeur de table si elle fait sens?
  2. Si ce n'est pas le cas, que faites-vous recommande d'éviter la duplication de code cela se produirait manuellement les annulant?
  3. Si c'est le cas, comment vous identifiez cela de l'exécution plan?

exemple de code:

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]

J'espère que l'échantillon a du sens.

Merci beaucoup pour votre aide!

Était-ce utile?

La solution

Dans ce cas, il s'agit d'une "fonction de valeur de table inline". L’optimiseur l’agrandit simplement (s’il est inutile) s’il est utile (ou affiché).

Si la fonction est traitée comme une " boîte noire " Dans la requête externe, le moyen le plus rapide consiste à comparer les E / S affichées dans SSMS et les E / S dans le profileur. Profler capture " boîte noire " IO que SSMS ne fait pas.

Article de blog d'Adam Mechanic (son livre est dans mon tiroir au travail)

Autres conseils

1) Oui, en utilisant votre syntaxe, c'est le cas. Si vous utilisiez un fichier UDF qui renvoyait une table contenant une logique conditionnelle, ce ne serait pas le cas.

3) L'optimiseur n'indique pas quelle partie de votre requête est en train d'optimiser, car il peut sembler utile de combiner des fragments du plan avec votre fonction ou d'optimiser des bits à distance.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top