【问题标题】:defering n:m lookup to stored procedure推迟 nm 查找存储过程
【发布时间】:2011-05-25 14:19:56
【问题描述】:

我有一组对象,它们可以是少数集合中的一个或多个的成员(想想可以位于树内多个位置的对象)。由于需要经常快速地查询这些分配,我们将它们作为单个“星座”id 存储在对象中,然后保留一个包含星座 id 的表,其中每个星座映射到多个集合(这也使我们免于一些与可能看起来更明显的 INNER JOIN 集合 WHERE set in (...) 方法相比,在区别方面存在问题。

示例:对象 1 和 2 都分配给集合 3 和 4。 而不是保留一个 n:m 列表

object id | set id
1           3
1           4
2           3
2           4

我们为对象 1 和 2 存储一个星座 id 5,然后有一个表将集合 3 和 4 分配给星座 5。由于对象往往被分配给集合的常见组合,这在实践中是可行的,即我们不t 需要保持 2^|sets| 的整个最坏情况周围有不同的星座。

查询当前可见集合s1、s2、...中至少一个内的所有对象,我们找到所有包含s1或s2或...的星座,然后创建查询WHERE constellation IN (constellation1, constellation2, constellation3, ...)

现在我们正在从 Access 转移到 SQL Server,问题是我们是否应该改变这种方法,因为我们实际上已经开始创建越来越大的 IN 子句。

我的问题是:这会是存储过程的用例吗?我想要一个像

这样的存储过程

SELECT * FROM objects WHERE IsInSet(s1, s2)

这个集合列表被转换成对应的星座集合,如果对象的星座包含在这个集合中,函数返回真。由于我只是迁移到 SQL Server 并且从未实际使用过存储过程,因此非常感谢任何有关这是否有意义的反馈。具体来说,我想知道 MSSQL 是否会以缓存星座设置表的方式对此进行优化,因为我们目前正在手动创建查询。

【问题讨论】:

    标签: sql-server database-design stored-procedures


    【解决方案1】:

    听起来您对FUNCTIONSSTORED PROCEDURES 之间的区别有些混淆。

    存储过程正是顾名思义——存储的SQL语句,批量执行,可以接受参数。它们主要用于创建一致的代码和/或执行计划,并通过使它们更加模块化和划分来简化复杂的流程。它们也便于代码重用。

    用户定义函数是传递参数并返回标量值或表,并且可以在查询中使用以返回分配给变量或行值的值(如UPDATE声明)。

    听起来您需要一个 table-valued-function 来返回一个表格,其中列出了包含您的值的所有集合,然后您可以在 JOIN 上打开。

    编辑:

    UDF 的替代方法是使用 exists 子句。在不真正了解您的表结构的情况下,例如:

    SELECT *
    FROM objects o
    WHERE EXISTS ( SELECT NULL
                   FROM Constellations c
                   INNER JOIN ConstellationLookup cl
                   WHERE c.set IN (s1,s2)
                   and cl.ObjectID = o.ObjectID)
    

    EXISTS 短路,所以它运行得非常快 - 它找到一个命中并向外部查询返回一个布尔值。

    【讨论】:

    • 酷,谢谢,是的,澄清绝对是第一步。考虑表值函数 - 所以我可以简单地查询“GetConstellations(s1, s2, ...) 中的 WHERE 星座”,其中 GetConstellation 将一组集合解析为一组星座。不过,您认为这是使用此类函数的合法方式还是深奥的方式(只是我已经意识到做一些奇怪的事情,这些事情在语法上有效,但在开始新领域时是不好的做法)
    • UDF 可能会导致难以追踪的性能问题。如果是我,我会在我的实际查询中写出逻辑。您有很多优化选项,我将添加一个示例。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-04-04
    • 1970-01-01
    • 1970-01-01
    • 2022-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多