想用mysql的的hash分区 对一张经常读取 数据量上千万的表进行分区处理 提高查询速率
但是卡在了建表这一步 ~~
这是自定义函数 func_get_hash(str);
传入一个字符串参数 返回一个整形值
BEGIN SET @seed = 131; SET @idx = 0; SET @hashValue = 0; SET @length = LENGTH(str); WHILE @idx <= @length DO SET @cCh = SUBSTRING(str,@idx,1); SET @hashValue = @hashValue * @seed + hex(@cCh); SET @idx = @idx + 1; END WHILE; return(@hashValue & 0x7FFFFFFF); END
下面是建表语句 其中id是字符串类型的 主键
CREATE TABLE `tbl_partition_test` ( `ch` varchar(50) DEFAULT NULL, `id` varchar(50) NOT NULL, `ph` varchar(50) , `create_time` datetime, PRIMARY KEY (`id`) #UNIQUE INDEX (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 PARTITION BY HASH(func_get_hash(id)) PARTITIONS 10;
[SQL]CREATE TABLE `tbl_partition_test` (
`ch` varchar(50) DEFAULT NULL,
`id` varchar(50) NOT NULL,
`ph` varchar(50) ,
`create_time` datetime,
PRIMARY KEY (`id`)
#UNIQUE INDEX (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
PARTITION BY HASH(func_get_hash(id))
PARTITIONS 10;
[Err] 1064 - Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed near ')
PARTITIONS 10' at line 9
提示 常量、随机或者依赖时区的表达式不能作为分区函数。
请各位大神 指点下 我需要改进什么~~~~
感激不尽~
没考虑hashvalue越界。楼主可以试下稍微长一点的字符串,该函数应该返回的都是0,个人建议是把*seed计算操作改成^seed等位操作。
另外,有个细节楼主要注意,length和char_length这两个函数对多字节字符集,返回值是不一样的。
是的长点的字符串都是0我发现了这个问题后来把与运算直接改成取模了因为算法方面我不是很懂我是百度别人C的算法修改成mysql可用的函数的谢谢您的指点但是修改函数之后依然不能成功的建立分区表请问还有哪些方面需要修改呢 不建议用mysql 自定义函数,建议直接分表,然后在程序里先计算出字符串的hash值。回复 @Hccake:用分区的方法,在where条件里也得加上分区的字段,不然会多分区扫描的。谢谢您的建议但是我们在讨论过程中分表建议被否决了因为这个需要改动代码而公司目前三个项目都需要做优化动作比较大经理目前希望我可以先通过物理分区暂时解决这个问题请问我要如何修改才可以使用自定义函数进行分区呢版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。