视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
SQL字段拆分优化
2020-11-09 07:03:09 责编:小采
文档


今天看到一条用函数处理连接的SQL,是群里某位网友的,SQL语句如下:

SELECT SO_Order.fdate ,
 SO_Order.fsn
FROM so_order
 INNER JOIN so_orderitem ON CHARINDEX(so_Orderitem.fid, SO_Order.fid) >= 1
WHERE so_order.FOrderDate = '2015-09-06'

语句不算复杂,只是执行比较慢,下面是关于这SQL语句的一些信息:

--1.SQL执行203条数据

--2.耗时12秒

--3.so_order表的fid字段是字符串集合,

--由1-2个字符串组成,用','分隔

SELECT COUNT(*)
FROM SO_Order
WHERE so_order.FOrderDate = '2015-09-06'--24
SELECT COUNT(*)
FROM so_Orderitem--414154

  通过分析执行计划,so_order和so_orderitem走嵌套循环是正确的,查询的瓶颈是在so_orderitem的索引

扫描上。因此,我们要通过改写SQL,达到so_orderitem走索引查找的目的。

  将so_order表的fid字段拆分成2个字段,然后union all成一个结果集,再和so_orderitem关联,即可让so_orderitem表走索引查找。

改写的SQL如下:

;WITH x0
 AS ( SELECT fdate ,
 fsn ,
 LEFT(fid, CASE WHEN CHARINDEX(',', fid, 1) = 0 THEN 0
 ELSE CHARINDEX(',', fid, 1) - 1
 END) AS fid
 FROM so_order
 WHERE FOrderDate = '2015-09-06'
 UNION ALL
 SELECT fdate ,
 fsn ,
 RIGHT(fid, LEN(fid) - CHARINDEX(',', fid, 1)) AS fid
 FROM so_order
 WHERE FOrderDate = '2015-09-06'
 )
 SELECT SO_Order.fdate ,
 SO_Order.fsn
 FROM x0 so_order
 INNER JOIN so_orderitem ON so_Orderitem.fid = SO_Order.fid

  下面是SQL改写后,网友的反馈截图

  改写后SQL的执行计划如下:


您可能感兴趣的文章:

  • MySQL优化之表结构优化的5大建议(数据类型选择讲的很好)
  • MySQL优化之如何查找SQL效率低的原因
  • mysql优化连接数防止访问量过高的方法
  • mysql优化limit查询语句的5个方法
  • MySQL优化GROUP BY方案
  • SQL优化之针对count、表的连接顺序、条件顺序、in及exist的优化
  • MySQL优化之对RAND()的优化方法
  • 21条MySQL优化建议(经验总结)
  • 人工智能自动sql优化工具--SQLTuning for SQL Server
  • Oracle 表三种连接方式使用介绍(sql优化)
  • mysql优化之路----hash索引优化
  • 下载本文
    显示全文
    专题