这是一个用max函数查询大范围数据的语句。经过查询计划发现,采集时间列没有索引,导致查询时会有扫描表的操作。后来给采集时间列加上索引,再采用不同的查询语句进行分析。以下是分析结果
-- 如果查询很大范围的数据库,发现使用max函数是效率最高的,其他的排序函数效率一般。
-- 因为采集时间是有序的
-- ----------------------使用max函数--------------------------
SET STATISTICS IO ON
DBCC DROPCLEANBUFFERS -- 关闭缓存
DBCC FREEPROCCACHE -- 关闭缓存
SELECT t.表地址, t.当前热量, t.热功率, t.瞬时流量, t.累计流量,
t.供水温度, t.回水温度, t.温差, t.累计工作时间, t.采集时间,
t.社区编号,t.楼房编号,t.房间号
FROM Measure_heat t
WHERE 采集时间 =
(
-- -很多时间花在这个地方,也就是如何能获得一个表的最近的采集时间。
select max (采集时间)
from measure_heat
where 表地址 = t.表地址
and 采集时间 >= ‘ 2013-11-11 ‘
and 采集时间 <= ‘ 2014-1-11 ‘
)
-- -------------------使用ROW_NUMBER函数-----------------------
-- create nonclustered index testMeasure_heat on Measure_heat (采集时间, 表地址)
SET STATISTICS IO ON
DBCC DROPCLEANBUFFERS -- 关闭缓存
DBCC FREEPROCCACHE -- 关闭缓存
-- 如果存在,删除缓存表
-- IF exists(SELECT * FROM #TableID)
-- 存入数据库内存表
SELECT * INTO #TableID FROM
(
SELECT ROW_NUMBER() OVER (PARTITION BY 房间号 ORDER BY 采集时间 DESC ) as rowID, id
FROM Measure_heat
WHERE 采集时间 >= ‘ 2013-11-1 ‘
AND 采集时间 <= ‘ 2014-1-11 ‘
-- AND 房间号 = 119
) T
WHERE T.rowID = 1
SELECT * FROM #TableID
SELECT t.表地址, t.当前热量, t.热功率, t.瞬时流量, t.累计流量,
t.供水温度, t.回水温度, t.温差, t.累计工作时间, t.采集时间,
t.社区编号,t.楼房编号,t.房间号
FROM Measure_heat T RIGHT JOIN #TableID b ON t.id = b.id
ORDER BY t.id
DROP table #TableID
-- ----------------------使用rank函数----------------------
DBCC DROPCLEANBUFFERS -- 关闭缓存
DBCC FREEPROCCACHE -- 关闭缓存
select * into #table2 from
(
SELECT 表地址, RANK() OVER (PARTITION BY 表地址 ORDER BY 采集时间) AS RankTest
FROM Measure_heat
WHERE 采集时间 >= ‘ 2013-11-1 ‘ AND 采集时间 <= ‘ 2014-1-11 ‘
) t
where ranktest = 1
-- SELECT * FROM #table2
SELECT t.表地址, t.当前热量, t.热功率, t.瞬时流量, t.累计流量,
t.供水温度, t.回水温度, t.温差, t.累计工作时间, t.采集时间,
t.社区编号,t.楼房编号,t.房间号
FROM Measure_heat T RIGHT JOIN #table2 a on a.表地址 = t.表地址
AND T.采集时间 BETWEEN ‘ 2013-11-1 ‘ AND ‘ 2014-1-11 ‘
drop table #table2
另一个使用Min函数的语句,性能也非常差
select t. * from Measure_heat t where 社区编号 = ‘ 13 ‘ and 采集时间 = ( select min (采集时间 ) from Measure_heat where 房间号 = t.房间号 AND 采集时间 >= ‘ 2013-11-6 ‘ AND 采集时间 < ‘ 2013-11-7 ‘ )
解决方法,在sql中建立内存表,先查出一部分,再利用第一部分的结果查询最终结果。最终可以秒查。
SET STATISTICS IO ON
DBCC DROPCLEANBUFFERS -- 关闭缓存
DBCC FREEPROCCACHE -- 关闭缓存
SELECT t. *
FROM Measure_heat t
WHERE 社区编号 = ‘ 13 ‘ and 采集时间 =
(
SELECT min (采集时间 )
FROM Measure_heat
where
采集时间 >= ‘ 2013-11-6 ‘
AND 采集时间 < ‘ 2013-11-7 ‘
AND 房间号 = t.房间号
)
ORDER BY t.id
-- ----------使用内存表------------
SET STATISTICS IO ON
DBCC DROPCLEANBUFFERS -- 关闭缓存
DBCC FREEPROCCACHE -- 关闭缓存
-- 如果存在,删除缓存表
-- IF exists(SELECT * FROM #TableID)
DROP table #TableID
-- 存入数据库内存表
SELECT * INTO #TableID FROM
(
SELECT ROW_NUMBER() OVER (PARTITION BY 房间号 ORDER BY 采集时间 desc ) as rowID, id
FROM Measure_heat
WHERE 采集时间 >= ‘ 2013-11-6 ‘
AND 采集时间 < ‘ 2013-11-7 ‘
AND 社区编号 = ‘ 13 ‘
) T
WHERE T.rowID = 1
-- SELECT * FROM #TableID
SELECT a. *
FROM Measure_heat a RIGHT JOIN #TableID b ON a.id = b.id
ORDER BY A.id
SQL Server性能优化(3)使用SQL Server Profiler查询性能瓶颈
标签:
查看更多关于SQL Server性能优化(3)使用SQL Server Profiler查询性能瓶颈的详细内容...
声明:本文来自网络,不代表【好得很程序员自学网】立场,转载请注明出处:http://haodehen.cn/did119522