怎样实现,一次查询多个参数,分别判断是否都是唯一的

1、实际需求:user表中,phone,username这两个字段都是唯一的,不能重复。批量插入之前需要分别判断这两个字段在数据库中是否已经存在。
2、当前解决方案:使用or来实现

SELECT
    COUNT(*)
FROM
    USER
WHERE
    phone = #{phone}
OR username = #{username}

3、问题:但是因为数据量比较大,效率很低,请问有什么更合适的解决方案,提供思路即可,谢谢。

阅读 6.7k
8 个回答

可以直接用mysql的 insert on duplicate key 来解决

https://dev.mysql.com/doc/ref...

你可以选择当唯一索引重复时,忽略插入或者删除

INSERT [IGNORE] INTO USER (phone, username,xxxxx ) values (#{phone},#{username}, xxxxx) 
[ ON DUPLICATE KEY UPDATE xxxxx = #{xxxxx}]

数据量很大可以考虑分表。

优化方案,可以考虑分两次查询,第一个不重复才去检查另一个,同时给这两个字段加索引。

可以使用数据库索引;为你不能重复的字段加唯一索引限制,插入的时候

考虑用exists来优化一下 另外增加phone和username联合索引

1、两个字段都有单独的唯一索引用union all查询判断结果不会慢的
2、利用mysql唯一索引的冲突异常,应用捕获异常也可以

我今天下午用mysql+navicat试了一下,100w条数据,
总共6组结果
1、无索引,union,平均0.7s
2、无索引,or,平均0.4s
3、两个唯一性索引,union,平均0.1s
4、两个唯一性索引,or,平均0.08
5、一个联合索引,union,平均0.4s
6、一个联合索引,or,平均0.4s

SELECT
    COUNT(*)
FROM
    (
        SELECT
            *
        FROM
            USER
        WHERE
            phone = "496066"
        UNION
            SELECT
                *
            FROM
                USER
            WHERE
                username = '888888'
    ) aa;


SELECT
    COUNT(*)
FROM
    USER
WHERE
    phone = '496066'
OR username = '888888';

前提:唯一索引
1、replace into 有,先删除再插入;无,直接插入。会有id间隙
2、insert ignore into 有,id空出来;无,插入。会有id间隙。
3、insert into on duplicate key update 有,则更新;无,则插入。

第二种第三种都用过,喜欢第三种,希望你也喜欢!

其实没必要count, limit 1就好,有则立即放回,没有第一个条件再查下一个

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题