【问题标题】:mySQL creating multiple temporary tablesmySQL 创建多个临时表
【发布时间】:2017-04-09 20:10:28
【问题描述】:

我在 mySQL 中有一个存储过程,它从表中获取数据子集并在临时表中对该子集执行一些分析。这是我的代码:

CREATE PROCEDURE GetPortfolioStats
(
    InIdx_i     INT,
    InStart_i   INT,
    InEnd_i     INT
)
BEGIN

DECLARE myLimit     INT;
DECLARE myOffset    INT;

SET myLimit = InEnd_i - InStart_i + 1;
SET myOffset = InStart_i - 1;

CREATE TEMPORARY TABLE IF NOT EXISTS myTmpTable AS (SELECT * FROM Leases WHERE Portfolio_i = InIdx_i ORDER BY Index_i LIMIT myLimit OFFSET myOffset);

SET @Additive_i := (SELECT COUNT(Index_i) FROM myTmpTable WHERE ReviewType_vc = 'Additive');
DROP TABLE myTmpTable;

SELECT @Additive_i;

END; GO

这很好用。但是,我遇到的问题是,这是一个多线程应用程序,当多个线程调用此存储过程时,它们开始共享同一个临时表,这会弄乱我正在尝试编译的 Stats。

有没有办法对存储过程的每次调用应用唯一的表名,或者将临时表的范围限制为存储过程的那个实例?

【问题讨论】:

    标签: mysql multithreading temp-tables


    【解决方案1】:

    回答具体问题:最简单的解决方案是每个线程使用不同的数据库连接,因为临时表是session (connection) specific

    您可以在创建表时使用 TEMPORARY 关键字。 TEMPORARY 表仅对当前会话可见,并在会话关闭时自动删除。这意味着两个不同的会话可以使用相同的临时表名称,而不会相互冲突或与现有的同名非临时表发生冲突。

    但是,在检查了实际代码之后,我建议根本不要使用临时表,使用带有子查询的单个查询:

    SELECT COUNT(Index_i)
    FROM
        (SELECT Index_i, ReviewType_vc
         FROM Leases
         WHERE Portfolio_i = InIdx_i
         ORDER BY Index_i
         LIMIT myLimit OFFSET myOffset) t
    WHERE ReviewType_vc = 'Additive'
    

    【讨论】:

    • 我也有类似的想法,但是(为简洁起见)我只展示了其中一个统计计算结果——大约有 14 个。因此,将相关行复制到临时表,然后计算 14 个统计信息更有意义。我会看看使用不同的连接。
    • 我刚刚尝试了您的解决方案,看看它是如何工作的,但我遇到了同样的问题。对于内部 SELECT,我添加了 AS T,然后进行了额外的分析。但是,我得到了错误的返回行数。当我在内部 SELECT 中使用“AS T”时,所有线程都可以看到“T”吗?
    • 最后的评论 - 如果我将 'POOLING=False' 添加到连接字符串,这是否意味着我从每个线程获得不同的连接?
    • 使用局部变量,而不是用户定义的变量(以@开头的变量是用户定义的变量)。用户定义的变量在会话级别共享。
    • 请在他们自己的帖子中提出任何后续问题(关于连接字符串)。
    猜你喜欢
    • 1970-01-01
    • 2013-03-01
    • 2010-11-21
    • 1970-01-01
    • 1970-01-01
    • 2021-03-18
    • 2018-12-30
    • 2013-10-18
    • 2016-03-15
    相关资源
    最近更新 更多