2015-11-07 51 views
7

我有存储创建临时表的过程。然后我想执行一个连接这些临时表的查询。有什么方法可以在Go中使用MySQL临时表?

问题是,使用Golang的数据库/ sql设计,确保为后续查询获得相同连接的唯一方法是创建一个事务。

如果我为了访问临时表的目的而将大部分SELECT选项包装在事务中,我是否会遇到麻烦?我知道我会失去一些性能/可伸缩性,因为我将坚持从池中的连接,而不是让他们回到查询之间。但我想知道我是否会开始看到这种策略的锁定或其他严重问题。

我需要这样做的原因是因为我的许多表的MySQL执行计划非常差(我在大表中进行了多次连接)。我想执行一些中间查询并将其结果存储在临时表中以避免此问题。

+0

即使是临时表吗?那么Golang中没有办法使用临时表? – william

+0

该文档指出创建临时表不会执行隐式提交(https://dev.mysql.com/doc/refman/5.6/en/implicit-commit.html),但是无法向其添加索引因为它会。 – william

+0

MySQL中的临时表只对当前连接可见。一旦连接关闭,它们将被丢弃。如果您使用的是临时表格,则在您开展业务时,您必须坚持这一关系。 – Code4aliving

回答

4

您可以创建自己的伪临时表,可以通过多个进程和连接来访问它们。

这个想法是简单地创建内存表,运行你的操作,然后清理。

您可以使用以下sql创建一个内存表;

CREATE TABLE mydb.temp_32rfd293 (
    id int(11) auto_increment, 
    content varchar(50), 
    PRIMARY KEY (`id`) 
) ENGINE=MEMORY; 

做一些有用的东西,然后使用拖放;

DROP TABLE temp_32rfd293: 

计划的活动,删除mydb.temp_%表年长超过1天

你要清理偶尔抛弃临时表,你可以在MySQL中建立一个计划的事件做这个。如果您选择这样做考虑使用临时表的专用模式来防止意外删除。

注意:您需要在您的my.ini中使用event_scheduler=ON才能正常工作。

DELIMITER $$ 

CREATE 
    EVENT `cleanup_custom_temps` 
    ON SCHEDULE EVERY 1 DAY STARTS '2000-01-01 01:00:00' 
    DO BEGIN 


    --------------------------------------------------- 
    -- Process to delete all tables with 
    -- prefix 'temp_', and older than 1 day 
    SET @tbls = (
    SELECT GROUP_CONCAT(TABLE_NAME) 
     FROM information_schema.TABLES 
     WHERE TABLE_SCHEMA = 'mydb' 
     AND TABLE_NAME LIKE 'temp_%' 
      AND CREATE_TIME < NOW() - INTERVAL 1 DAY 
); 
    SET @delStmt = CONCAT('DROP TABLE ', @tbls); 
    PREPARE stmt FROM @delStmt; 
    EXECUTE stmt; 
    DEALLOCATE PREPARE stmt; 
    --------------------------------------------------- 

    END */$$ 

DELIMITER ; 
相关问题