mysql 索引列 or_MySQL学堂之避免索引列使用OR条件

在我们使用MySQL数据库进行查询时如果通过使用包含OR条件的索引列来进行查询的话往往得出的数据量是非常大的,这就给我们的工作造成极大的不便。那么我们有什么方法来避免索引列使用包含OR条件的索引列呢?为此在本篇文章中课课家笔者就此向大家作出详细的方法介绍以供大家参考参考。

8d7026ea5caa7b5cbb3cc160d6cade95.png

下面笔者就OR的弊端给大家作出详细的介绍:

aadd01818b53c8a0a756b1b6258a2bb1.png

从上述查询语句我们不难看出f_mobile和f_phone两个字段都有可能存电话号码,一般我们的思路都是用OR去一条sql解决,但如果表数据量一大就很麻烦了:

c4fec3696243b659006446dbe22653f7.png

我们不难发现t_tbanme1上有索引idx_id_mobile(f_xxx_id,f_mobile),idx_phone(f_phone),idx_id_email(f_id,f_email),explain的结果却使用了idx_id_email索引,有时候运气好可能走idx_id_mobilef_xxx_id。

我们知道MySQL的每条查询,每个表上只能选择一个索引,如果我们使用了idx_id_mobile索引而恰好有一条数据因为有limit1,那么我们则很快得到结果,但是如果f_mobile没有数据,那么f_phone字段只能在f_id条件下挨个查找并扫描12w行。

下面是优化sql的两种方法介绍(注意f_mobile,f_phone上都要有相应的索引):

【Method 1】

3455f0e3c1dd73d9df9b83ffeaa04c1c.png

a242593b58866ad8c392b5c1bf4af4c1.png

我们不难发现两条独立的sql都能用上索引,分查询各自limit。如果都有结果集返回我们则随便取一条就可以了。

下面笔者给大家介绍第二种优化办法。如果查询特别频繁且无缓存,改成单独的sql执行,比如大部分号码值都在f_mobile上,那我们可以通过先执行分sql1,如果判断有结果则结束,判断没有结果再执行分sql2。这种方法能够有效减少数据库查询速度从而让代码去处理更多的事情。

【Method 2】

5974a2df5f10893dfc21a02e0cb6b52f.png

另外如果是复杂一点的场景则不止返回一条记录那么简单,limit2:

62b389dd1c8bc4adc3e825c5d5ead369.png

遇到这种情况时我们则需要对【Method 1】、【Method 2】进行修改,因为f_create_time,f_modify_time都可能均满足判断条件,如此一来就会返回重复的数据。

【Method 1】的修改:

5087178341a976dfc300bd8b9c1902d1.png

此时部分人或许会说把UNION ALL改成UNION不就去重了吗?如果说查询比较频繁或者limit比较大,数据库还是会有压力,所以我们还需要做trade off。这种情况更多还是适合【Method 2】,包括有可能需要ORder by limit情况。

【Method 2】的修改:

6e28348a6361c0e1edbc2b2883ec616e.png

PS:相同字段OR可改成in,比如f_id=1ORf_id=100->f_idin(1,100)。上述优化情景都是存储引擎在InnoDB情况下,而在MyISAM却有所不同。

以上就是避免索引列使用OR条件的方法介绍,如果大家觉得笔者的方法可以的话不妨收藏一下吧。另外如果大家觉得笔者的文章中有不足的地方时笔者欢迎大家对本文章中出现的讲解提出自己的个人建议,对出现错误的地方提出批评,笔者会诚心接纳大家的建议和批评,并根据大家提出的建议和批评作出相应的修改工作。如果大家还想浏览更多相关的内容欢迎到网 站的IT文库浏览文章哦!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值