SQL Server:内联表值UDF与内联视图

cra*_*aig 5 sql t-sql sql-server user-defined-functions

我正在使用医疗记录系统,该系统将数据存储在类似于电子表格的构造中 - 列标题中的日期/时间,每行第一列中的测量值(例如医生姓名,Rh,血型)和值在相交的细胞中.基于此构造的报告通常需要显示10个或更多这些度量.

出于报告目的,数据集需要每个患者有一行,测量的日期/时间以及每个测量的列.实质上,需要将构造旋转90度.

有一次,我实际上使用SQL Server的PIVOT功能来做到这一点.由于各种原因,很明显这种方法不起作用.我决定使用内联视图(IV)将数据按到所需的格式.简化的查询类似于:

SELECT patient_id, 
       datetime, 
       m1.value AS physician_name, 
       m2.value AS blood_type, 
       m3.value AS rh
  FROM patient_table
INNER JOIN ( complex query here
              WHERE measure_id=1) m1...
INNER JOIN (complex query here
              WHERE measure_id=2) m2...
LEFT OUTER JOIN (complex query here
                 WHERE measure_id=3) m3...
Run Code Online (Sandbox Code Playgroud)

如您所见,在某些情况下,这些IV用于限制结果数据集(INNER JOIN),在其他情况下,它们不限制数据集(LEFT OUTER JOIN).但是,除了measure_id的不同之外,"复杂查询"部分对于这些度量中的每一个都基本相同.虽然这种方法有效,但它会导致相当大的SQL语句,限制重用,并将查询暴露给错误.

我的想法是用内联表值UDF替换'复杂查询'和WHERE子句.这将简化查询,减少错误并增加代码重用.我唯一想到的问题就是表现.UDF方法会导致性能显着下降吗?它可以改善问题吗?

感谢您的时间和考虑.

Rem*_*anu 8

正确定义的TVF不会引入任何问题.与视图或临时表和变量相比,您会发现许多关于性能问题的实施爆破TVF的声明.通常不被理解的是,TVF的行为与视图不同.将View定义放入原始查询中,然后优化器将按其认为合适的方式重新排列查询树(除非在索引视图上使用NOEXPAND子句).TVF具有不同的语义,有时,特别是在更新数据时,这导致TVF输出被假脱机以保护haloween.它有助于标记该函数WITH SCHEMABINDING,请参阅使用T-SQL UDF上的SCHEMABINDING选项改进查询计划.

同样重要的是理解确定性和精确功能的概念.虽然它们主要适用于标量值函数,但TVF也会受到影响.请参阅用户定义的功能设计指南.


Stu*_*rth 1

您还有第三种选择;传统的视图(假设您有密钥可以加入)。理论上,这三个选项之间不应该存在性能差异,因为 SQL Server 应该相应地评估和优化计划。现实情况是,有时情况并没有我们希望的那么好。

传统视图的好处是您可以将其设为索引视图,并为 SQL Server 提供另一种性能帮助;但是,您只需测试一下即可。

  • 索引视图与 Oracle 的物化视图相同。该视图必须符合某些限制:http://msdn.microsoft.com/en-us/library/ms191432.aspx,并且只有企业版才会考虑使用索引视图进行数据访问。标准版及更低版本必须通过添加 NOEXPAND 提示显式强制使用 iindexed 视图,请参阅 http://msdn.microsoft.com/en-us/library/ms181151.aspx (2认同)