我有一张非常大的下注交易表。让我们说,为了这个问题,我想找一些去年下注但不是在下个月投注的人的账户,所以我这样做......
--query one
select accountnumber into #wageredrecently from activity
where _date >='2011-08-10' and transaction_type = 'Bet'
group by accountnumber
--query two
select accountnumber,firstname,lastname,email,sum(handle)
from activity a, customers c
where a.accountnumber = c.accountno
and transaction_type = 'Bet'
and _date >='2010-09-10'
and accountnumber not in (select * from #wageredrecently)
group by accountnumber,firstname,lastname,email
问题是,这需要年龄来获取数据。有没有更快的方法在sql中实现相同的目标?
编辑,只是为了具体说明时间:它需要超过3分钟,这对于发往php内部网页的查询来说太长了。
编辑(2011年11月9日):我发现问题是客户表。这实际上是一种观点。它以前有很好的性能,但现在突然间它的性能很糟糕,对它的简单查询几乎和上面的查询对一样长。因此,我选择了另一个客户数据表(实际上是一个表,而不是一个视图),现在查询对大约需要15秒。
答案 0 :(得分:1)
在找到并汇总customers
中的行后,您应该尝试加入activity
(我假设handle
是activity
中的一列)。
select c.accountno,
c.firstname,
c.lastname,
c.email,
a.sumhandle
from customers as c
inner join (
select accountnumber,
sum(handle) as sumhandle
from activity
where _date >= '2010-09-10' and
transaction_type = 'bet' and
accountnumber not in (
select accountnumber
from activity
where _date >= '2011-08-10' and
transaction_type = 'bet'
)
group by accountnumber
) as a
on c.accountno = a.accountnumber
我还将您的第一个查询作为子查询包含在内。我不确定这对性能会有什么影响。它可能会更好,可能更糟,你必须测试你的数据。
答案 1 :(得分:1)
我不知道您确切的业务需求,但很少有人需要在几个月内立即通知您无效的帐户。根据您何时获取数据,这可能会变得更糟。
您可以创建一个indexed view,其中包含每个帐户的最后一个交易日期:
max(_date)as RecentTransaction
如果此表格过大,可能会按活动的年份或月份分配。
答案 2 :(得分:0)
您是否考虑过将_date
的索引添加到activity
表?这可能需要很长时间,因为当您比较日期时,它必须对该列进行全表扫描。此外,transaction_type
也被编入索引吗?否则,另一个指数对你没有好处。
答案 3 :(得分:0)
回答我的问题,因为问题不是查询的结构,而是使用其中一个表。这是一种观点,其表现非常糟糕。我将客户数据更改为实际表格,并将执行时间缩短至约15秒。