求大神指点,下面的语句,是否有优化空间(注:索引已调整到最佳),可否从语句写法方面入手:
SELECT
u.username,
u.userid,
u.province,
u.dotadmin,
t.tickets,
u.viplevel,
u.regdata,
u.maintainlevel,
d.staffname,
d.staffid
FROM subsidiaryreportsystem.dbo.distributorstaffmapping d WITH (NOLOCK)
LEFT JOIN subsidiaryreportsystem.dbo.tbluser u WITH (NOLOCK)
ON d.userid = u.userid
LEFT JOIN
(
SELECT userid, sum (ticketnums) tickets
FROM subsidiaryreportsystem.dbo.ticketmonitor WITH (NOLOCK)
WHERE date > '2014-2-1 0:00:00' AND date < '2014-2-28 23:59:59'
GROUP BY userid
) t
ON d.userid = t.userid
LEFT JOIN subsidiaryreportsystem.dbo.tblspecialuser s WITH (NOLOCK)
ON s.userid = d.userid
WHERE s.userid IS NULL
AND u.admin = 1
AND d.staffid = 318924
AND u.province = '江苏'
ORDER BY tickets DESC
我做了如下更改(使用子查询,去掉了s表的连接),执行计划是少了很多,但是效率基本没变:
SELECT TOP 100
u.username,
u.userid,
u.province,
u.dotadmin,
t.tickets,
u.viplevel,
u.regdata,
u.maintainlevel,
d.staffname,
d.staffid
from
(
select
userid,
staffname,
staffid
FROM
subsidiaryreportsystem.dbo.distributorstaffmapping WITH (NOLOCK)
where
staffid = 318924
) d
inner join
(
select
username,
userid,
province,
dotadmin,
viplevel,
regdata,
maintainlevel
from
subsidiaryreportsystem.dbo.tbluser WITH (NOLOCK)
where
admin = 1
AND province = '江苏'
) u
on d.userid=u.userid
left join
(
SELECT
userid,
sum (ticketnums) tickets
FROM
subsidiaryreportsystem.dbo.ticketmonitor WITH (NOLOCK)
WHERE
date > '2014-02-01 0:00:00' AND date < '2014-02-28 23:59:59'
GROUP BY userid
) t
ON d.userid = t.userid
order by tickets
------解决方案--------------------
很正常的语句,在语句上应该没有太大的改善空间了,还是考虑下索引,如果允许的话用一些带include的大索引,还有就是
SELECT userid, sum (ticketnums) tickets
FROM subsidiaryreportsystem.dbo.ticketmonitor WITH (NOLOCK)
WHERE date > '2014-2-1 0:00:00' AND date < '2014-2-28 23:59:59'
GROUP BY userid
这个聚合可以先计算存储到一个表,一段时间内做一次增量或者全量的更新,然后使用这个表做查询。
------解决方案--------------------
SELECT
userid,
sum (ticketnums) tickets
FROM
subsidiaryreportsystem.dbo.ticketmonitor WITH (NOLOCK)
WHERE
date > '2014-02-01 0:00:00' AND date < '2014-02-28 23:59:59'
GROUP BY userid
这个过滤了还有10W啊?
------解决方案--------------------
初步结果:
1、你的TicketMonitor表索引不合理,先加这个:
USE [SubsidiaryReportSystem]
GO
CREATE NONCLUSTERED INDEX IX_TicketMonitor_Include
ON [dbo].[TicketMonitor] ([Date])
INCLUDE ([UserID],[TicketNums])
GO
2、TicketMonitor这个表的聚集索引放到一个没用到的ID列上,单纯从这个语句来看比较浪费,PK可以设在ID上,不过聚集索引可以考虑移开。比如移到userid上。
3、你的表TicketMonitor有没有做分区?如果没有,在上面两步做完还没比较明显的改进后,可以按月分区