【问题标题】:Should you use temporary tables to pass data between stored procedures?您应该使用临时表在存储过程之间传递数据吗?
【发布时间】:2009-11-12 13:27:26
【问题描述】:

我有许多搜索函数(存储过程),它们需要返回具有完全相同列的结果。

这是采取的方法:

每个存储过程都有一般结构:

CREATE TABLE #searchTmp (CustomerID uniqueIdentifier)

INSERT INTO #searchTmp
SELECT C.CustomerID FROM /**** do actual search here, based
                              on stored proc arguments ****/

EXEC spSearchResults

DROP TABLE #searchTmp

在上面,spSearchResults 在选择中使用#searchTmp 表。 spSearchResults 总是会返回一个包含相同列的表,并且有很多连接。

但是,与其使用临时表,不如使用以下方法更容易接受:

SELECT col1, col2, col3, col4, .... etc, lots of columns ... FROM table1 LEFT JOIN table 2 ON ... etc, lots of joins ... WHERE ... DO ACTUAL SEARCH HERE ...

如果要进行 10 种不同的搜索(例如,根据邮政编码搜索客户,根据姓氏搜索等),则第二种方法意味着存在大量重复的列和指定的连接。如果使用搜索功能的代码发生变化,需要返回一个新列,那么就有 10 个存储过程需要更新。

我完全赞成第一种方法,但我只是想知道第二种方法有什么好处。表现?

或者有第三种方法吗?

【问题讨论】:

    标签: sql performance temp-tables


    【解决方案1】:

    只要临时表的内容代表要输出的最终组唯一键,并且之后不对结果集进行进一步修剪,那么这是实现您的要求的一种非常有效的方法.

    只有当临时表包含一组中间键,这些键在后续查询中被进一步缩减时,才会出现问题。在这种情况下,在一个查询中读取所有数据会更有效率。

    编辑: 正如 Mark 所说,由于查询优化器能够在单个查询方法中使用多个线程,但在临时表方法中却不能,因此可能存在性能差异。您必须权衡这种潜在收益与临时表方法可维护性的巨大改进,并决定哪个对您更重要。与数据库问题一样,最好衡量性能而不是猜测。

    【讨论】:

      【解决方案2】:

      第二个应该表现更好。这将是您要返回的数据的较小比例。

      第二个使查询优化器有机会按照它想要的任何顺序进行查询,第一个强制首先从第一个表中进行选择(在您的情况下很可能是想要的)。您也可以使用并行第二个查询,即多个线程处理查询,优化器可以执行此操作。

      要对此进行检查,请运行 Showplan(Sybase 或 SQL Server)或 EXPLAIN (Iracle) 等以查看生成的实际查询。

      【讨论】:

        【解决方案3】:

        如果使用 Microsoft Sql Server,我更喜欢第三种方法:

        Create Function GetSearchKeys([Search parameters here])
        Returns @Keys Table (pk Int Primary Key Not Null)
        As
        Begin
              Insert @Keys(pk)
              Select C.CustomerID 
              From /**** do actual search here, based 
                       on Search parameters ****/
              Return
        End
        
          -- ----------------------------------------------------
        

        然后,在每个存储过程中,

          SELECT col1, col2, col3, col4, .... etc, lots of columns ... 
          FROM table1 
             LEFT JOIN table 2 
                ON ... etc, lots of joins
             Join schema.GetSearchKeys([Search parameters here]) K
                on K.pk = [whatever table.column has the primary key in  it]
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-08-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-06-11
          • 2010-09-22
          相关资源
          最近更新 更多