千锋教育-做有情怀、有良心、有品质的职业教育机构

400-811-9990
手机站
千锋教育

千锋学习站 | 随时随地免费学

千锋教育

扫一扫进入千锋手机站

领取全套视频
千锋教育

关注千锋学习站小程序
随时随地免费学习课程

上海
  • 北京
  • 郑州
  • 武汉
  • 成都
  • 西安
  • 沈阳
  • 广州
  • 南京
  • 深圳
  • 大连
  • 青岛
  • 杭州
  • 重庆
当前位置:成都千锋IT培训  >  技术干货  >  WHERE中有很多IN判断怎么提速?

WHERE中有很多IN判断怎么提速?

来源:千锋教育
发布人:xqq
时间: 2023-10-17 21:04:10

一、WHERE中有很多IN判断怎么提速

WHERE 中的 IN 是要过滤出某字段值包含在给定枚举值集合中的记录,比如:查出某几个城市的客户、某些类型的订单等等。

数据库做 IN 过滤时,要用字段值和值集合的成员作比较计算。若采用顺序查找,要比较 1 到 n 次(n 是值集合大小)。即使在值集合有序的情况下用二分法查找,也要比较数次。数据量较大时比较次数会非常多,IN 的速度就会很慢,而且值集合越大速度越慢。

如果在过滤时不再做比较计算,性能就能得到大幅提高!

首先,确定 IN 可能取值的列表。可能值通常不会太多,一般都保存在一个选项表中。如果没有现成的选项表,要遍历原数据得到所有可能值,保存成一个选项表。然后转换原数据,把 IN 字段值替换为选项表中对应记录的序号(位置),另存成一份新数据。

对替换后的新数据做 IN 判断时,先生成一个与选项表等长的布尔值集合,其第 i 个值由选项表的第 i 个成员是否在 IN 的值集合中决定,在就是 true,不在就是 false。

然后遍历新数据,用 IN 字段值(也就是选项表的序号)去取布尔值集合中的成员,是 true 就符合过滤条件,否则就不符合。

这种方法本质上是将“集合值比较”转换为“序号引用”,省去了比较计算,性能会大幅提升。而且计算时间和值集合大小无关,不会随着 IN 枚举值的增多而增加。

但是,SQL 不支持通过序号(位置)直接取集合中的成员,无法实现这种优化方法。

集算器 SPL 支持序号引用,可以很方便的实现这个优化方法。

1、 数据预处理,转换为序号。

=cs.run(dim1.pos@b(f1):f1),遍历原数据,使用 pos 函数查到原数据 f1 字段在选项表 dim1 中对应记录的序号,用这个序号代替原来的 f1 字段值,另存一份新数据。dim1 预先按照 f1 对应值排好序了,所以这里采用二分法查找,预处理的速度更快。

2、 对预处理好的新数据做 IN 过滤计算。

假设传入值集合为 arg_F1,生成布尔值集合的代码是:

b1=dim1.(arg_F1.contain@b(~)),arg_F1 有序,所以这里也是二分法查找。

然后就可以用新方法过滤新数据了:

=file(“T.ctx”).open().cursor(…;b1(f1) && …),用 f1 中的序号,直接去取布尔值集合中的成员,成员是 true 则满足过滤条件,否则就不满足。这时不需要再做比较计算,性能会大幅提高。

实测表明,在同等硬件环境下,用 SPL 实现的这种方案比 Spark 上的 SQL 快了上百倍。

延伸阅读:

二、联合索引 (a,b,c)

联合索引 (a,b,c) 实际建立了 (a)、(a,b)、(a,b,c) 三个索引。

我们可以将组合索引想成书的一级目录、二级目录、三级目录,如index(a,b,c),相当于a是一级目录,b是一级目录下的二级目录,c是二级目录下的三级目录。要使用某一目录,必须先使用其上级目录,一级目录除外。

联合索引的优势

1) 减少开销

建一个联合索引 (a,b,c) ,实际相当于建了 (a)、(a,b)、(a,b,c) 三个索引。每多一个索引,都会增加写操作的开销和磁盘空间的开销。对于大量数据的表,使用联合索引会大大的减少开销!

2)覆盖索引

对联合索引 (a,b,c),如果有如下 sql 的,

 

SELECT a,b,c from table where a=’xx’ and b = ‘xx’;

那么 MySQL 可以直接通过遍历索引取得数据,而无需回表,这减少了很多的随机 io 操作。减少 io 操作,特别是随机 io 其实是 DBA 主要的优化策略。所以,在真正的实际应用中,覆盖索引是主要的提升性能的优化手段之一。

3)效率高

索引列多,通过联合索引筛选出的数据越少。比如有 1000W 条数据的表,有如下SQL:

 

select col1,col2,col3 from table where col1=1 and col2=2 and col3=3;

复制

假设:假设每个条件可以筛选出 10% 的数据。

A. 如果只有单列索引,那么通过该索引能筛选出 1000W10%=100w 条数据,然后再回表从 100w 条数据中找到符合 col2=2 and col3= 3 的数据,然后再排序,再分页,以此类推(递归);B. 如果是(col1,col2,col3)联合索引,通过三列索引筛选出 1000w10% 10% *10%=1w,效率提升可想而知。
声明:本站稿件版权均属千锋教育所有,未经许可不得擅自转载。

猜你喜欢LIKE

sql server2012r2所在服务器做端口限制,需要开放什么端口才能继续访问数据库?

2023-10-17

Oracle有什么优势和劣势?

2023-10-17

CSS 隐藏页面元素有哪些方法?

2023-10-17

最新文章NEW

数据库聚集索引非聚集索引实现上有哪些区别?

2023-10-17

开发web应用,好的开发流程是怎么样的?

2023-10-17

为什么说Gradle是Android进阶绕不去的坎?

2023-10-17

相关推荐HOT

更多>>

快速通道 更多>>

最新开班信息 更多>>

网友热搜 更多>>