查询优化,查询时间太久了,如何优化?

Jakey_Ch 2014-07-29 11:50:39
有如下一个存储过程,执行该存储过程平均每次需要10秒左右,
为什么会需要这么长的时间呢?是数据表太大了的问题呢?
还是我的存储过程有问题呢(是不是UNION ALL太耗时间了啊)?
有办法优化吗?

DECLARE @SQL varchar(max)
SET @SQL = ''

SELECT @Sql =
@Sql + 'SELECT
[Project_Name],
[Station],
[Barcode_SN]
FROM '
+ NAME + ' A WITH(NOLOCK),
(SELECT
MAX(ID) AS ID
FROM
' + NAME + ' WITH(NOLOCK)
GROUP BY [Project_Name], [Barcode_SN], SUBSTRING([Station] , 0 , charindex(''_'', [Station]))) B
WHERE A.ID = B.ID' +
' AND A.[Upload_DateTime] >= ' + '''' + @StartTime + '''' +
' AND A.[Upload_DateTime] < ' + '''' + @EndTime + '''' +
' UNION ALL '
FROM
SYS.TABLES
WHERE
LEFT(NAME, '9') = 'LOG_INFO_'

SET @SQL = LEFT(@SQL, LEN(@SQL)-10)

SELECT @Sql = 'SELECT
[Project_Name] as ''product'',
[Station] as ''station_id''
FROM '
+ '(' + @Sql + ') t'
+' GROUP BY
[Project_Name],
[Station]'

EXEC(@SQL)
...全文
340 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
Jakey_Ch 2014-07-29
  • 打赏
  • 举报
回复
额,执行计划是这个吗?

引用 1 楼 DBA_Huangzj 的回复:
3、如果很慢,贴执行计划,ctrl+m然后执行语句


Jakey_Ch 2014-07-29
  • 打赏
  • 举报
回复
引用 1 楼 DBA_Huangzj 的回复:
1、print语句出来

SELECT 
					[Project_Name],
					[Station],
					[Barcode_SN]
				FROM LOG_INFO_N90 A WITH(NOLOCK),
					(SELECT   
						MAX(ID) AS ID
				     FROM     
						LOG_INFO_N90 WITH(NOLOCK)		
				     GROUP BY [Project_Name], [Barcode_SN], SUBSTRING([Station] , 0 , charindex('_', [Station]))) B
				WHERE	A.ID = B.ID AND A.[Upload_DateTime] >= '20140727070000' AND A.[Upload_DateTime] < '20140727070100' UNION ALL SELECT 
					[Project_Name],
					[Station],
					[Barcode_SN]
				FROM LOG_INFO_N31CG_WM A WITH(NOLOCK),
					(SELECT   
						MAX(ID) AS ID
				     FROM     
						LOG_INFO_N31CG_WM WITH(NOLOCK)		
				     GROUP BY [Project_Name], [Barcode_SN], SUBSTRING([Station] , 0 , charindex('_', [Station]))) B
				WHERE	A.ID = B.ID AND A.[Upload_DateTime] >= '20140727070000' AND A.[Upload_DateTime] < '20140727070100' UNION ALL 
SELECT 
					[Project_Name],
					[Station],
					[Barcode_SN]
				FROM LOG_INFO_N31CG_BM A WITH(NOLOCK),
					(SELECT   
						MAX(ID) AS ID
				     FROM     
						LOG_INFO_N31CG_BM WITH(NOLOCK)		
				     GROUP BY [Project_Name], [Barcode_SN], SUBSTRING([Station] , 0 , charindex('_', [Station]))) B
				WHERE	A.ID = B.ID AND A.[Upload_DateTime] >= '20140727070000' AND A.[Upload_DateTime] < '20140727070100' UNION ALL 
SELECT 
					[Project_Name],
					[Station],
					[Barcode_SN]
				FROM LOG_INFO_Kingkong_WM A WITH(NOLOCK),
					(SELECT   
						MAX(ID) AS ID
				     FROM     
						LOG_INFO_Kingkong_WM WITH(NOLOCK)		
				     GROUP BY [Project_Name], [Barcode_SN], SUBSTRING([Station] , 0 , charindex('_', [Station]))) B
				WHERE	A.ID = B.ID AND A.[Upload_DateTime] >= '20140727070000' AND A.[Upload_DateTime] < '20140727070100' UNION ALL 
SELECT 
					[Project_Name],
					[Station],
					[Barcode_SN]
				FROM LOG_INFO_K93_white A WITH(NOLOCK),
					(SELECT   
						MAX(ID) AS ID
				     FROM     
						LOG_INFO_K93_white WITH(NOLOCK)		
				     GROUP BY [Project_Name], [Barcode_SN], SUBSTRING([Station] , 0 , charindex('_', [Station]))) B
				WHERE	A.ID = B.ID AND A.[Upload_DateTime] >= '20140727070000' AND A.[Upload_DateTime] < '20140727070100' UNION ALL 
SELECT 
					[Project_Name],
					[Station],
					[Barcode_SN]
				FROM LOG_INFO_Kingkong_BM A WITH(NOLOCK),
					(SELECT   
						MAX(ID) AS ID
				     FROM     
						LOG_INFO_Kingkong_BM WITH(NOLOCK)		
				     GROUP BY [Project_Name], [Barcode_SN], SUBSTRING([Station] , 0 , charindex('_', [Station]))) B
				WHERE	A.ID = B.ID AND A.[Upload_DateTime] >= '20140727070000' AND A.[Upload_DateTime] < '20140727070100' UNION ALL 
SELECT 
					[Project_Name],
					[Station],
					[Barcode_SN]
				FROM LOG_INFO_PN_White A WITH(NOLOCK),
					(SELECT   
						MAX(ID) AS ID
				     FROM     
						LOG_INFO_PN_White WITH(NOLOCK)		
				     GROUP BY [Project_Name], [Barcode_SN], SUBSTRING([Station] , 0 , charindex('_', [Station]))) B
				WHERE	A.ID = B.ID AND A.[Upload_DateTime] >= '20140727070000' AND A.[Upload_DateTime] < '20140727070100'
太多了,没办法完全显示,共30几张表 2、直接执行print出来的语句,看看会不会很慢 执行19张表时,耗时4秒左右
發糞塗牆 2014-07-29
  • 打赏
  • 举报
回复
1、print语句出来 2、直接执行print出来的语句,看看会不会很慢 3、如果很慢,贴执行计划,ctrl+m然后执行语句
發糞塗牆 2014-07-29
  • 打赏
  • 举报
回复
绝大部分情况下不会出问题,但是如果数据量很大,会花点时间,你最好在没有数据操作时做
Jakey_Ch 2014-07-29
  • 打赏
  • 举报
回复
引用 11 楼 DBA_Huangzj 的回复:
默认主键就是聚集索引,但是可以改,看执行计划你的表没有聚集索引,所以出现表扫描
谢谢版主,明白了,看那些有主键的表的话,都是有聚焦索引的。 那在这个表还在插入数据的时候,对这个表建立聚焦索引(设置主键)和建立非聚焦索引的话,会出问题吗? 还是要等到没有使用的时候呢?
發糞塗牆 2014-07-29
  • 打赏
  • 举报
回复
默认主键就是聚集索引,但是可以改,看执行计划你的表没有聚集索引,所以出现表扫描
Jakey_Ch 2014-07-29
  • 打赏
  • 举报
回复
引用 9 楼 DBA_Huangzj 的回复:
好了?
表暂时不敢动,等无数据插入(即这个数据库不提供对外服务)的时候,再建索引, 据说建立索引有点耗时,而且作为小白,不知道在数据表还在被使用的情况下建立索引会不会出现什么问题。 所以只好等数据表未被使用的时候来做这个动作了。 【然后查看了表设计,ID居然不是主键,蛋蛋的忧伤~】 如果一个键是主键的话,是不是相当于就是一个聚焦索引了?
發糞塗牆 2014-07-29
  • 打赏
  • 举报
回复
好了?
Jakey_Ch 2014-07-29
  • 打赏
  • 举报
回复
引用 5 楼 luckyrandom 的回复:
设计问题,非改这个SQL能大幅提长效率
那如何能提高效率呢?我是小白,不懂,望指点~
發糞塗牆 2014-07-29
  • 打赏
  • 举报
回复
1、每个表的ID加一个聚集索引, 2、每个表的[Upload_DateTime]加一个非聚集索引
Jakey_Ch 2014-07-29
  • 打赏
  • 举报
回复
引用 4 楼 DBA_Huangzj 的回复:
是这个,但是执行计划应该不是那么简单的,那么多表union all,你把整个语句一起执行,如果执行计划太大,贴出百分比最大的那几部分,另外,你的表能加索引吗?都是表扫描不是很合理

是需要用print出来的语句来看 执行计划吗?
用的存储过程的语句的执行计划是这样的额:


用print的SQL语句的部分执行计划(没写全,只写了19个):




Q315054403 2014-07-29
  • 打赏
  • 举报
回复
设计问题,非改这个SQL能大幅提长效率
發糞塗牆 2014-07-29
  • 打赏
  • 举报
回复
是这个,但是执行计划应该不是那么简单的,那么多表union all,你把整个语句一起执行,如果执行计划太大,贴出百分比最大的那几部分,另外,你的表能加索引吗?都是表扫描不是很合理

27,580

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 应用实例
社区管理员
  • 应用实例社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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