我正在尝试在两个表上应用连接,需要应用连接的列的值不相同,因为我需要使用concat,但问题是需要很长时间才能运行。所以这是一个例子:
我有两张桌子:
表:MasterEmployee 字段:varchar(20)id,varchar(20)name,Int age,varchar(20)status
表:员工 字段:varchar(20)id,varchar(20)指定,varchar(20)名称,varchar(20)状态
我有不变的前缀:08080
固定长度为1个字符的后缀,但值是随机的。
员工中的id = 08080 + {MasterEmployee中的id} + {1 char random value}
MasterEmployee:
<9>,约翰,24岁,批准了888,Leo,26岁,等待
员工:
080809991,开发人员,约翰,已批准
080808885,Tester,Leo,已批准
select * from Employee e inner join MasterEmployee me
on e.id like concat('%',me.id,'%')
where e.status='approved' and me.status='approved';
还有更好的方法吗?因为我需要在非常大的数据集上运行相同类型的查询。
答案 0 :(得分:1)
这不是concat
问题,标量操作非常便宜。问题是像你一样使用like
。 field like '%...'
形式的任何内容都会自动跳过索引,从而导致扫描操作 - 我认为这是显而易见的原因。
如果你必须拥有这个代码,那么就是这样,你无能为力,你必须放弃你将要承担的巨大性能。如果可能的话,我会重新考虑你的数据库方案或你解决它的方式。
编辑:重读它,您想要的是连接前缀,以便您的查询采用field like '08080...'
形式。这将使用您可能拥有的任何指数。
答案 1 :(得分:1)
使用静态前缀08080
肯定会更好,这样DBMS就可以使用索引。它不会使用带有LIKE
和前导通配符的索引:
SELECT * FROM Employee e INNER JOIN MasterEmployee me
ON e.id LIKE CONCAT('08080', me.id, '_')
AND e.status = me.status
WHERE e.status = 'approved';
请注意,我已将status
添加到JOIN条件,因为您希望Employee.status
与MasterEmployee.status
匹配。
此外,由于您只有一个后缀字符,因此您可以使用单字符通配符_
代替%
。