请问此SQL如何优化?

leon51 2018-10-08 09:16:29
下面的语句中,我原将第17行写成:
 m17.inv_part_number LIKE a.生产部件+'%'

但是结果不正确(单独运行此句是OK的),改为:
LEFT(m17.inv_part_number, 12) = LEFT(a.生产部件, 12)

后结果正确,但速度下降得非常厉害,请问怎么优化?

SELECT
a.生产部件,
a.客户名称,
a.订单类型,
a.下单时间,
b.套板尺寸X,
b.套板尺寸Y,
b.拼板尺寸X,
b.拼板尺寸Y,
b.大料尺寸长,
b.大料尺寸宽,
(SELECT TOP 1 SUBSTRING(d17.inv_part_description,1,CHARINDEX(' ',d17.inv_part_description)- 1)
FROM data0026 d26,data0025 d25, data0017 m17, data0017 d17
WHERE d26.parent_node_invent = d25.rkey AND d25.inventory_ptr = m17.rkey
AND d26.inventory_ptr = d17.rkey
AND d17.inv_part_number LIKE 'AA%'
AND LEFT(m17.inv_part_number, 12) = LEFT(a.生产部件, 12) COLLATE Chinese_PRC_BIN) AS 物料,
b.板料利用率,
b.拼板利用率
FROM GC_DATA001 a
LEFT JOIN PE_套板尺寸信息 b
ON a.生产部件 = b.型号 COLLATE Chinese_PRC_BIN
WHERE (下单时间 BETWEEN CONVERT(DATETIME, '2018-10-01', 102) AND CONVERT(DATETIME, '2018-10-08', 102))
...全文
217 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
吉普赛的歌 版主 2018-10-09
  • 打赏
  • 举报
回复
优化在大部分情况下是需要添加索引的, 光改下语句就快起来不现实。 让有权限的人去增加列和索引吧。
leon51 2018-10-09
  • 打赏
  • 举报
回复
引用
@二月十六 没事, 我再发一次吧。
感谢版主的回复,可惜我没有权限创建索引和修改表。 去掉物料列后速度很快,物料与生产部件都放在data0017表中,此表有30万条记录。 能否先得到除物料以外的结果,然后在此基础上增加物料列呢? data0017表中的inv_part_number值为一个长度大于或等于12的字符串,它的前12位等于GC_DATA001表中型号
二月十六 版主 2018-10-09
  • 打赏
  • 举报
回复
引用 6 楼 leon51 的回复:
1楼的写法一样的慢

引用
试试这样呢
m17.inv_part_number LIKE LEFT(a.生产部件, 12)+'%'

那就用5#版主的吧,加一列专门用来查询用
leon51 2018-10-09
  • 打赏
  • 举报
回复
1楼的写法一样的慢
引用
试试这样呢 m17.inv_part_number LIKE LEFT(a.生产部件, 12)+'%'
吉普赛的歌 版主 2018-10-09
  • 打赏
  • 举报
回复
@二月十六 没事, 我再发一次吧。
--每个表添加一个可持久化计算列,并添加对应索引
--1.1
ALTER TABLE data0017 ADD inv_part_number_left12 AS LEFT(inv_part_number,12) PERSISTED
CREATE INDEX ix_data0017_inv_part_number_left12 ON data0017(inv_part_number_left12)
--1.2
ALTER TABLE GC_DATA001 ADD part_left12 AS LEFT([生产部件],12) PERSISTED
CREATE INDEX ix_GC_DATA001_part_left12 ON GC_DATA001(part_left12)
--如果下单时间没有索引,应该加一个:
CREATE INDEX ix_GC_DATA001_orderTime ON _GC_DATA001([下单时间])


--执行完上面的, 再执行查询
SELECT
	a.生产部件,
	a.客户名称,
	a.订单类型,
	a.下单时间,
	b.套板尺寸X,
	b.套板尺寸Y,
	b.拼板尺寸X,
	b.拼板尺寸Y,
	b.大料尺寸长,
	b.大料尺寸宽,
	(SELECT TOP 1 SUBSTRING(d17.inv_part_description,1,CHARINDEX(' ',d17.inv_part_description)- 1)
	FROM data0026 d26,data0025 d25, data0017 m17, data0017 d17
	WHERE d26.parent_node_invent = d25.rkey AND d25.inventory_ptr = m17.rkey 
		AND d26.inventory_ptr = d17.rkey
		AND d17.inv_part_number_left12 LIKE 'AA%'	--反正左边 12 个字符逻辑也对得上,有索引的列效率更高
		AND m17.inv_part_number_left12 = a.part_left12  COLLATE Chinese_PRC_BIN --这里改成了计算列直接连接
	) AS 物料,
	b.板料利用率,	                
	b.拼板利用率
FROM GC_DATA001 a
LEFT JOIN PE_套板尺寸信息 b
ON a.生产部件 = b.型号 COLLATE Chinese_PRC_BIN 
WHERE (下单时间 BETWEEN CONVERT(DATETIME, '2018-10-01', 102) AND CONVERT(DATETIME, '2018-10-08', 102))
二月十六 版主 2018-10-08
  • 打赏
  • 举报
回复
试试这样呢
 m17.inv_part_number LIKE LEFT(a.生产部件, 12)+'%'

34,576

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧