sql - 为什么运行过程非常非常慢?
问题描述
ALTER procedure [dbo].[PSI]
@`PartNo` nvarchar (50),
@Customer nvarchar (50),
@Date1 Date,
@Date2 Date
AS
Begin
declare @Qty int,
@i int,
@max_i int,
@b nvarchar(15),
@j int,
@max_j int
IF EXISTS (SELECT * FROM tempdb.sys.sysobjects WHERE name like '#Test%')
DROP TABLE #Test
create table #Test(
IDX int identity(1,1),
Item nvarchar(50)
)
insert into #Test(Item) select distinct Name_Customer from Master_Products where Name like '%' + @PartNo + '%' and Customer like '%' + @Customer + '%'
set @i=0
set @max_i=DATEDIFF(day, @Date1, @Date2)
Set @Qty=2
DECLARE @SQL NVARCHAR(200)
DECLARE @SQL1 NVARCHAR(200)
DECLARE @x int
DECLARE @y int
DECLARE @z int
while @i<=@max_i
begin
set @j=1
set @max_j=(SELECT MAX(IDX) FROM #Test)
Set @b=Dateadd(day,@i,@Date1)
Set @SQL='alter table #Test
add [' + cast(@b AS NVARCHAR(10)) + ']' + + 'int'
exec [sp_executesql] @sql WITH RECOMPILE
while @j<=@max_j
Begin
Set @x=(SELECT SUM(Qty)
FROM Planning_Stock_Balance
WHERE DateAjust<=@b and (select top 1 name from Master_Products where Name=Planning_Stock_Balance.PartNo) =(select item from #Test where IDX=@j))
Set @y=(SELECT SUM(OKQTY) FROM Injection_Daily_Result WHERE PRODATE<=@b and (select top 1 name from Master_Products where Name=Injection_Daily_Result.PartNo)=(select item from #Test where IDX=@j))
Set @z=(SELECT SUM(Qty) FROM Sales_PO WHERE DeliDate<=@b and (select top 1 name from Master_Products where Name=Sales_PO.ItemCode)=(select item from #Test where IDX=@j))
Set @SQL1 ='update #Test
set [' + cast(@b AS NVARCHAR(10)) + ']=' + CAST(isnull(@x,0)+isnull(@y,0)-isnull(@z,0)
AS NVARCHAR(10))
+ ' where idx =' + cast(@j as NVARCHAR(10)) +''
exec [sp_executesql] @sql1 WITH RECOMPILE
SET @j=@j+1
end
SET @i=@i+1
end
Select * from #Test
OPTION ( OPTIMIZE FOR UNKNOWN )
-- where Item like '%' + @PartNo + '%' and (select top 1 Customer from Master_Products where Name=Item) like '%' + @Customer +'%'
IF OBJECT_ID(N'tempdb..#Test', N'U') IS NOT NULL
drop table #Test
End
解决方案
这段代码非常晦涩,不清楚您要实现什么。
一些提示:
使用有意义的变量名,例如@stock_balance
,而不是变量名,如@x
等。这种命名约定@y
的缺乏使得代码难以遵循,不仅对局外人而且对你也是如此。
通常,在设计合理的关系数据库中,您将通过ID或一些唯一键而不是像您在这里所做的那样按名称处理客户:
and Customer like '%' + @Customer + '%'
这是非常不安全的:想想如果您有多个同名或相似名称的客户会发生什么。
更不用说这样的where
子句将不能使用索引,假设你甚至有一个。
如果您在运行过程时显示执行计划,它应该会显示需要很长时间的部分(或者您可以简单地print getdate()
在代码中添加一些部分)。
动态 SQL 不仅危险而且很少有正当理由。必须有更好的方法来做到这一点。
您在过程中使用了许多表,其结构未知。您应该做的是发布这些表的结构,显示一些示例数据,并提供预期结果的示例。
推荐阅读
- javascript - 首次单击后按钮的作用相反
- java - SonarQube 一直抱怨 Use try-with-resources 或在“finally”子句中关闭此“PreparedStatement”
- r - ggsave 不保存绘图
- sql - 在 PostgreSQL IF / THEN 语句中使用 DELETE FROM...RETURNING
- php - PhpStorm 或 localhost 中的结帐后 + Docker
- r - R - 结转 1 直到达到另一个 1
- sql-server - 包括每个客户的 companyID 并将其链接到其他表 SQL
- c++ - 模拟队列的链表堆栈不起作用
- android-studio - 我在使用 AndroidStudio 的“构建文件夹下的文件”中遇到错误
- c - C语言中的霍夫变换有问题