mysql改进or查询_mysql or查询优化

上午朋友问我一条sql优化方案,因采用or全表扫描查询,导致查询速度过慢(2s多),问我有没有优化方案,具体sql如下:

set @search = 'yd12015';

SELECT `pwd_flag`,`username`,`uid`,`email`,`user_status` FROM `member` WHERE

(

`user_status` >=0 and `email_status`=0 and (`username`=@search or `email`=@search or `phone`=@search)

) LIMIT 1;逻辑意思为:查询用户表审核通过&&未锁定&&(用户名或者邮箱或者电话号码为具体字符串)的用户信息,放在自己服务器上测试,当menber表数据量达到100w级别时,查询耗时大约在1.5s左右,这是在没有并发的情况,如果存在并发,那就没得救了。得优化!

仔细思考这条sql需要得到的用户数据,发现是可以有优化方案的,首先想到的是用union查询,然后得到的sql如下:

set @search = 'yd12015';

SELECT `pwd_flag`,`username`,`uid`,`email`,`user_status` FROM `member` WHERE

(

`user_status` >=0 and `email_status`=0 and `username`=@search

)

union

SELECT `pwd_flag`,`username`,`uid`,`email`,`user_status` FROM `member` WHERE

(

`user_status` >=0 and `email_status`=0 and `email`=@search

)

union

SELECT `pwd_flag`,`username`,`uid`,`email`,`user_status` FROM `member` WHERE

(

`user_status` >=0 and `email_status`=0 and `phone`=@search

)

limit 1

检测查询时间,瞬间将至0.1s以下,这是妥妥的性能提升啊,可取!

第二个方案是,根据查询字符串,优化查询sql,因查询的是用户名,邮箱,电话,所以可以先判断字符串的类型,来查询对应的字段,比如,如果既不是邮箱,也不是电话,就没必要去扫描这2个字段了。如果单纯是邮箱格式,那就不可能是电话号码。

注:union的用法及一些需要注意事项:  union:联合的意思,即把两次或多次查询结果合并起来。  要求:两次查询的列数必须一致  推荐:列的类型可以不一样,但推荐查询的每一列,想对应的类型以一样  可以来自多张表的数据:多次sql语句取出的列名可以不一致,此时以第一个sql语句的列名为准。  如果不同的语句中取出的行,有完全相同(这里表示的是每个列的值都相同),那么union会将相同的行合并,最终只保留一行。也可以这样理解,union会去掉重复的行。 如果不想去掉重复的行,可以使用union all。  如果子句中有order by,limit,需用括号()包起来。推荐放到所有子句之后,即对最终合并的结果来排序或筛选。 如:(select * from a order by id) union (select * from b order id); 在子句中,order by 需要配合limit使用才有意义。如果不配合limit使用,会被语法分析器优化分析时去除。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值