【问题标题】:Should I make table-valued functions for common large joins SQL我应该为常见的大型连接 SQL 创建表值函数吗
【发布时间】:2012-05-08 13:54:57
【问题描述】:

只使用了几个月的 SQL(到目前为止,这个地方帮助很大,谢谢大家!) 但即使我是一个初学者数据库程序员,我已经注意到有很多大型连接我发现自己一遍又一遍地重复。我正在考虑为常用的连接创建一个表值函数,并允许将参数传递给该函数以过滤结果。

例如。 而不是写

SELECT * 
FROM T1 join T2 on T1.A = T2.A 
        join T3 on T2.B = T3.B
        join T4 on T3.C = T4.D
WHERE T1.D = '15' AND T2.D = '20' AND T3.C = '12'

我会写

SELECT * 
FROM dbo.SOME_FUNCTION(' T1.D = '15' AND T2.D = '20' AND T3.C = '12' ')

我的问题就是这个。这是我应该尝试做的事情吗?还是我懒得做这个?

整天都在尝试研究/编写这个函数,并且在这样做时遇到了很多/很多问题。我知道最终我可以/将使它发挥作用,只是想知道这是否值得我花时间。

PS:对不起,如果这个问题很愚蠢,不是我想在这个网站上问的第一个问题,但这里是。

【问题讨论】:

  • 这不是一个愚蠢的问题,您正在努力提高效率。但是,DRY 原则在应用于关系数据库编程时具有显着的性能影响,因此在该上下文中应用它时要小心(例如,不要使用嵌套视图(即,引用其他视图的视图)、多语句表值函数的性能不如内联函数(请参阅 (stackoverflow.com/questions/2554333/…),不要在标量函数中运行选择查询等)。您必须在性能和优雅之间取得平衡

标签: tsql join sql-function query-parameters


【解决方案1】:

表值函数是避免重复 SELECT 语句的好方法,但它不是唯一的方法。我会将这些语句放在一个视图中,因为它可以被索引。您仍然可以使用表值函数,它使用参数从视图中选择记录。

想象一下,从您的角度来看,您有以下 2 种类型的检索:

1,SELECT ... WHERE Column1 = @p1

2、SELECT ... WHERE Column2 = @p2 AND Column3 = @p3

在这种情况下,您应该将匹配的两个索引添加到视图中

  • 第 1 列

  • 列 2 + 列 3

【讨论】:

  • 是的,问题是我使用的 WHERE/SELECT 列通常不同。此外,这些表很大(每张数百万 + 行),所以直接查看会很紧张。
  • @user1329267:视图不在乎有多少行......创建视图的哪个方面会很紧张?
  • @user1329267:我会尝试一下:)您视图中包含的所有行都将根据您的索引首选项进行索引。
【解决方案2】:

我认为也许您的想法是合理的,但方法并不理想。可能有两种体面的方法可以解决这个问题。首先是创建一个视图:

CREATE VIEW dbo.SOME_VIEW AS
(
    SELECT 
        -- [list out the columns here], do not use *
    FROM 
        T1 
    JOIN 
        T2 on T1.A = T2.A 
    JOIN 
        T3 on T2.B = T3.B
    JOIN 
        T4 on T3.C = T4.D
)

这样,您的查询是:

SELECT * FROM SOME_VIEW
WHERE ...

函数方法可以工作,但我会将函数更改为接受三个参数,而不是您在示例中显示的单个字符串方法,以便您改为这样做:

SELECT * FROM dbo.SOME_FUNCTION('15', '20', '12')

同样,根据您访问数据的方式,存储过程可能更合适:

EXEC dbo.spSomeStoredProcedure @T1D = '15', @T2D = '20', @T3C = '12'

编辑:表值函数和存储过程都应该使用上面的视图。

【讨论】:

  • 是的,问题是我使用的 WHERE/SELECT 列通常不同。一旦连接完成,最终会有大约 25 列,这就是为什么我正在考虑传递一个字符串(许多问题发生在一个函数中返回和 EXEC QUERY ......)
猜你喜欢
  • 1970-01-01
  • 2017-03-28
  • 2012-01-31
  • 2020-05-01
  • 2016-11-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多