最近有这样的需求,由于早期数据库表设计有些问题,为了加速查询速度将几个关联表合并到一张表中,最开始想的是一个字段一个字段进行入库更新。类似于
update tb_userinfo_0 a set avatar_update_count = (select b.update_count from tb_anothertable_0 b where a.uid=b.uid);
但效率太低时间上无法忍受。
在网上一顿神搜,终于找到一个可行的方案。
1.创建主表的备份
2.将主表重命名成临时使用的表
3.将主表和关联表的数据写到一张临时表中去
4.添加字段或者修改字段
5.将临时表命名成主表的名字
6.删除掉第2步产生的临时表
主要用到了以下的sql语句:
begin set @p0 = 'create table ht_userinfo_'; set @p1 = ' (select * from ht_userinfo_'; set @pcmd0=concat(@p0,table_index ,'_bak',@p1,table_index,');'); prepare pstmt0 from @pcmd0; execute pstmt0; set @s0 = 'alter table ht_userinfo_'; set @s1 = ' rename to userinfotemp_'; set @cmd0=concat(@s0,table_index ,@s1,table_index); prepare stmt0 from @cmd0; execute stmt0; set @str1 = ' Create table new_table_name (Select a.* , b.c_code as a_code, b.c_bg as a_bg, b.update_count as a_update_count, b.update_time as a_update_time, c.current_xml as xml, c.update_count as f_update_count, c.update_time as f_update_time from userinfotemp_'; set @str2 = ' a left join tb_user_avatar_'; set @str3 =' b on a.uid=b.uid left join tb_user_fashion_'; set @str4 =' c on a.uid=c.uid);'; set @cmd=concat(@str1,table_index ,@str2,table_index ,@str3,table_index ,@str4); prepare stmt from @cmd; execute stmt; alter table new_table_name add primary key(id); alter table new_table_name add `pshow_link` varchar(100) DEFAULT NULL; alter table new_table_name add `pshow_update_time` datetime DEFAULT NULL; alter table new_table_name add `pshow_update_count` bigint(20) DEFAULT 0; update new_table_name set a_update_count = 0 where a_update_count is null; update new_table_name set f_update_count = 0 where f_update_count is null; alter table new_table_name modify a_update_count bigint(20) DEFAULT '0'; set @sss0 = 'alter table new_table_name'; set @sss1 = ' rename to ht_userinfo_'; set @sscmd0=concat(@sss0 ,@sss1,table_index); prepare ssstmt0 from @sscmd0; execute ssstmt0; set @ss0 = 'drop table userinfotemp_'; set @scmd0=concat(@ss0 ,table_index); prepare sstmt0 from @scmd0; execute sstmt0; end
其中tableindex 是传入参数
写的有些乱,但是还是可以看懂的。
正式上线出了个大问题,由于来回导表把索引弄没了,导致查询极其缓慢有时一条要30s,把数据库的服务器的cpu占满了,昨晚紧急升级加上索引问题解决。
剩下一个疑惑:为什么查会跑到主库上去?