sql-server - 查询计划优化器是否适用于连接/过滤的表值函数?

标签 sql-server sql-server-2005 tsql query-optimization user-defined-functions

在 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]

我希望示例有意义。

非常感谢您的帮助!

最佳答案

在这种情况下,它是一个“内联表值函数” 如果有用(或查看),优化器会简单地扩展(取消嵌套)它。

如果函数被外部​​查询视为“黑盒”,最快的方法是比较 SSMS 中显示的 IO 与分析器中的 IO。 Profiler 捕获 SSMS 不捕获的“黑匣子”IO。

Blog post by Adam Mechanic (他的书在我上类的抽屉里)

关于sql-server - 查询计划优化器是否适用于连接/过滤的表值函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/311026/

相关文章:

sql - 如何以编程方式将非身份列更改为身份一?

sql-server - 向表中添加 BLOB 字段的性能开销

sql - 从日期计算中排除周末和自定义日期(即假期)

sql-server-2005 - 将数字转换为字母

sql - 从表中删除共享相同 ID 的所有行

sql - COALESCE 的逆

sql - 如何授予 SQL Server 代理访问权限以便能够写入/修改系统文件?

SQL : Comparing multiple values in one table with a single value in another Table

sql - UNION ALL 和 NOT IN 在一起

c# - 将事务回滚到保存点失败的 ALTER TABLE ... ADD CONSTRAINT