我有一个分片数据库,它是来自多个可用源的结果,但有些数据库没有所有公共列的数据。我基于源代码进行分片,因此整个结果表电流获得一个列 char(1( 并且所有值都设置为 ''。导入数据后,除极少数例外情况外,数据将仅读取。
有没有更好的方法来告诉 mysql 始终为给定列返回 null 或 '' 结果?我测试了 char(0(,但它强制进行表扫描。不想查找表格布局来静态选择列(选择 '' 作为 ip(。
有结果 (ip(
CREATE TABLE `shard1` (
`id` int(11) NOT NULL,
`type` varchar(128) NOT NULL DEFAULT '',
`message` TEXT NOT NULL DEFAULT '',
`ip` varchar(39) NOT NULL
PRIMARY KEY (`id`),
KEY `type` (`type`),
KEY `ip` (`ip`,`type`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8
没有结果 (ip(
CREATE TABLE `shard2` (
`id` int(11) NOT NULL,
`type` varchar(128) NOT NULL DEFAULT '',
`message` TEXT NOT NULL DEFAULT '',
`ip` char(1) NOT NULL
PRIMARY KEY (`id`),
KEY `type` (`type`),
KEY `ip` (`ip`,`type`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8
选择通常是这样的
SELECT type,message,ip FROM shard1 WHERE id = 123;
SELECT message,ip FROM shard1 WHERE ip = '127.0.0.1';
SELECT message,ip FROM shard1 WHERE type = 'error' and ip = '127.0.0.1';
这是对系统的过于简化的表示。最小的分片表只有 27 行,最大的分片表超过 500m 行。目前的性能是可以接受的,大约 0.05 秒,但我一直很想让事情变得更有效率。
似乎我想出了一个可能的解决方案,使用带有静态空字符串作为 ip 的视图。以前从未真正使用过视图,但优化器在视图中足够智能,但在主表中则不然。
查看在此语句上创建的test
SELECT id,type,message,'' as ip FROM shard2
优化器足够聪明,可以知道任何搜索,但"即使像"%anything%"这样的ip是即时的(0.001秒(,即使没有我正在测试的10m行表上的ip索引,也不会产生任何结果。
SELECT message,ip FROM test WHERE ip LIKE '%1';
同样为了解释该语句,优化器认为这是一个"不可能的 WHERE",因此软件实际上没有从表中获取任何结果。
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
我想每天都要学习新东西。