当前位置: 代码迷 >> Sql Server >> 多表UNION 查询优化解决办法
  详细解决方案

多表UNION 查询优化解决办法

热度:22   发布时间:2016-04-24 10:13:58.0
多表UNION 查询优化
上次这么个提问帖,数据查询时间过久:
http://bbs.csdn.net/topics/390845989
查询语句如下:

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]'

PRINT(@SQL)
EXEC(@SQL)

本来查询时间是10秒左右,现在给每张表的ID加了主键(聚焦索引),Upload_DateTime字段加了非聚焦索引,然后现在查询时间是16秒以上了~~~为什么???甚觉不科学啊~~~
------解决方案--------------------
上执行计划来看看。
------解决方案--------------------
未加任何索引之前,应该是使用表扫描的方式;加了聚集索引之后,由于首先是要group by那3个字段,但是那3个字段未加索引,所以应该会发生聚集索引扫描,对全部索引进行一次扫描,然后还要使用键查找来反查那3个字段,最后再对3个字段进行group by,感觉应该这个地方最耗时了,所以比直接全表扫描还慢。
考虑在3个group by字段上加覆盖索引,试试效果。
------解决方案--------------------
基本都是聚集索引扫描 这样效率就不会太高了。
------解决方案--------------------
2楼的截图是加了索引之后的情况是吧?
------解决方案--------------------
现在执行这些语句的执行计划是怎样的?
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'
  相关解决方案