这样的情况一个sql语句怎么写?
可以的. 参考 高性能mysql, Writing a lazy UNION 这一节, 给出sql如下:
- SELECT GREATEST(@found := -1, id) AS id
- FROM messages WHERE card_no = 'xxxxxxxxxxx'
- UNION ALL
- SELECT id
- FROM messages WHERE card_no like '%xxxxxxxxxxx%' AND @found IS NULL
- UNION ALL
- SELECT 1 FROM DUAL WHERE ( @found := NULL ) IS NOT NULL;
解释一下:
第一个select:
"SELECT GREATEST(@found := -1, id) AS id FROM messages where id ='xxx'"
--如果where 没有找到记录, 则select里 greatest函数不会被执行, 所以变量 @found为NULL; 如果where找到记录, 则select里 greatest函数 执行, 变量 @found被赋值为-1. 因为id都是正整数, 所以GREATEST(@found := -1, id)的值肯定是id;
第二个select:
-- @found为NULL则 此select不会执行, mysql引擎也不会去做 card_no like '%xxxxxxxxxxx%' 操作;
第三个select:
-- 重置@found变量.
首先用 '=' 方式做匹配, 好处是可以用到索引; 匹配不到再 'like' 操作. 因为'绝大部分都是一个卡号,即长度为16位', 所以性能还可以.
性能考虑
当然这里 like 需要走整个messages表, 而且不能索引. 所以还是很慢, 可以考虑更新一下表结构:
这就很类似 <<高性能mysql>>, Writing a lazy UNION 这一节 给出的那个sql了, 分别从'users' 和'users_archived'两张表里查询 用户信息. 可以仔细揣摩一下.
PS: 没必要用mediumtext类型.