我有一堆MySQL查询使用临时表将复杂/昂贵的查询拆分成小块。
create temporary table product_stats (
product_id int
,count_vendors int
,count_categories int
,...
);
-- Populate initial values.
insert into product_stats(product_id) select product_id from product;
-- Incrementally collect stats info.
update product_stats ... join vendor ... set count_vendors = count(vendor_id);
update product_stats ... join category... set count_categories = count(category_id);
....
-- Consume the resulting temporary table.
select * from product_stats;
问题在于,当我使用连接池时,即使关闭java.sql.Connection
,这些表也不会被清除。
我可以在执行所需的查询之前逐个手动删除它们(drop temporary table x;
),但这可能会发生错误。
有没有办法(JDBC / MySQL,API /配置)重置当前会话中创建的所有临时表而不关闭数据库连接(如您所知,我不是要java.sql.Connection.close()
),这样我仍然可以利用提供连接池的优势吗?
编辑:
似乎只有MySQL版本5.7.3才开始实现“重置连接”功能。 (发行说明:https://dev.mysql.com/doc/relnotes/mysql/5.7/en/news-5-7-3.html)但是,我暂时不会使用它,因为5.7版本仍在开发版本中。
答案 0 :(得分:0)
问:有没有办法(JDBC / MySQL,API /配置)重置当前会话中创建的所有临时表而不关闭数据库连接。
答:否。没有"重置"可用。您可以在会话中发出DROP TEMPORARY TABLE foo
个语句,但必须提供要删除的临时表的名称。
规范模式适用于创建临时表以删除它的进程,在连接返回池之前。 (我通常在finally
块中处理此问题。)
如果我们期望其他进程可能会在会话中留下临时表(并且是防御性的,这是我们所期望的),我们通常会在尝试创建临时表之前执行DROP TEMPORARY TABLE IF EXISTS foo
。
修改强>
上述答案对于MySQL版本5.6来说是正确的。
@ mr.Kame(OP)指出新的 mysql_reset_connection
功能(在MySQL 5.7.3中引入)。
看起来这个新功能实现了与我们通过断开连接并重新连接到MySQL所获得的几乎相同的结果,但开销更少。
(现在我想知道MariaDB是否引入了类似的功能。)