mysql改进or查询_mysqlor查询优化
上午朋友问我⼀条sql优化⽅案,因采⽤or全表扫描查询,导致查询速度过慢(2s多),问我有没有优化⽅案,具体sql如下:
t @arch = 'yd12015';
SELECT `pwd_flag`,`urname`,`uid`,`email`,`ur_status` FROM `member` WHERE
(
`ur_status` >=0 and `email_status`=0 and (`urname`=@arch or `email`=@arch or `phone`=@arch)
) LIMIT 1;逻辑意思为:查询⽤户表审核通过&&未锁定&&(⽤户名或者邮箱或者电话号码为具体字符串)的⽤户信息,放在⾃⼰服务器上测试,当menber表数据量达到100w级别时,查询耗时⼤约在1.5s左右,这是在没有并发的情况,如果存在并发,那就没得救了。得优化!
仔细思考这条sql需要得到的⽤户数据,发现是可以有优化⽅案的,⾸先想到的是⽤union查询,然后得到的sql如下:
t @arch = 'yd12015';
SELECT `pwd_flag`,`urname`,`uid`,`email`,`ur_status` FROM `member` WHERE
(
`ur_status` >=0 and `email_status`=0 and `urname`=@arch
)
union
SELECT `pwd_flag`,`urname`,`uid`,`email`,`ur_status` FROM `member` WHERE
(
云峰湖`ur_status` >=0 and `email_status`=0 and `email`=@arch
欧阳修是什么居士>互文性
)95什么意思
union
SELECT `pwd_flag`,`urname`,`uid`,`email`,`ur_status` FROM `member` WHERE
(
羊绒大衣怎么洗
`ur_status` >=0 and `email_status`=0 and `phone`=@arch
)
limit 1惹人喜爱的近义词
汉字字体检测查询时间,瞬间将⾄0.1s以下,这是妥妥的性能提升啊,可取!
第⼆个⽅案是,根据查询字符串,优化查询sql,因查询的是⽤户名,邮箱,电话,所以可以先判断字符串的类型,来查询对应的字段,⽐如,如果既不是邮箱,也不是电话,就没必要去扫描这2个字段了。如果单纯是邮箱格式,那就不可能是电话号码。排骨玉米冬瓜汤
注:union的⽤法及⼀些需要注意事项: union:联合的意思,即把两次或多次查询结果合并起来。 要求:两次查询的列数必须⼀致 推荐:列的类型可以不⼀样,但推荐查询的每⼀列,想对应的类型以⼀样 可以来⾃多张表的数据:多次sql语句取出的列名可以不⼀致,此时以第⼀个sql语句的列名为准。 如果不同的语句中取出的⾏,有完全相同(这⾥表⽰的是每个列的值都相同),那么union会将相
同的⾏合并,最终只保留⼀⾏。也可以这样理解,union会去掉重复的⾏。 如果不想去掉重复的⾏,可以使⽤union all。 如果⼦句中有order
by,limit,需⽤括号()包起来。推荐放到所有⼦句之后,即对最终合并的结果来排序或筛选。 如:(lect * from a order by id) union (lect * from b order id); 在⼦句中,order by 需要配合limit使⽤才有意义。如果不配合limit使⽤,会被语法分析器优化分析时去除。