Oracle - 在有大量数据的表上需要多次计数的建议
问题描述:
有大数据的表,有人知道如何优化count语句吗?例如:表预订(ID,电子邮件,手机,...)(约30个字段)。Oracle - 在有大量数据的表上需要多次计数的建议
Function GetBookingCount(p_email, p_mobile) return number
Select count(id)
from Booking
Where email = p_email
or mobile = p_mobile
Function GetBookingStatus3Count(p_email, p_mobile) return number
Select count(id)
from Booking
Where (email = p_email or mobile = p_mobile)
and status = 3;
最终选择:
Select GetBookingCount(email, mobile) as BookingCount
, GetBookingStatus3Count(email, mobile) as BookingStatus3Count
, ...
From Booking
where ....
解决方法1:设置在WHERE子句中算作电子邮件列,移动,状态栏什么的字段列索引。
解决方案2:创建一个包含少量列的新表。 新表:Booking_Stats(id,电子邮件,手机,状态)。
感谢您的任何建议。
答
预订表应该有一个关于电子邮件,手机和状态的索引。你应该使用这个选择:
WITH B1 AS
(
SELECT ID,
COUNT(ID) CNT1,
STATUS
FROM BOOKING
WHERE EMAIL = P_EMAIL
AND MOBILE = P_MOBILE
)
SELECT CNT1,
COUNT(ID) CNT2
FROM B1
WHERE STATUS = 3;
答
select count(*) count_all, count(case when status=3 then 1 else null end) count_status_3
from Booking
where email = p_email and mobile = p_mobile
//注意:(电子邮件,移动查询从头写的,没有测试
你会考虑创建上(电子邮件,手机)或索引,状态)取决于你得到的给定(电子邮件,移动设备)的行数,你将支付更新状态改变索引的费用(如果允许的话)。如果同一行的状态有很多更新,您可能更喜欢仅索引(电子邮件,手机)[读/写成本折衷]。
电子邮件很可能是非常区分的(一个值会过滤大部分列)。如果不是这种情况,请考虑将订单更改为(手机,电子邮件),如果移动列是更好的候选人。
答
似乎所有这些功能都没有帮助,实际上对性能无害。
您还没有发布一套完整的要求(什么是...
意思?),所以这是很难确定的,但它很可能是沿着这些路线的解决方案会更表演:
with bk as (
select *
from booking
where email = p_email
or mobile = p_mobile
)
select count(*) as BookingCount
, count(case when bk.status = 3 then 1 end) as BookingStatus3Count
, ...
from bk
想法是查询基表一次,获取计算所有计数所需的所有数据,并在尽可能最小的结果集上计算聚合。
booking(email,mobile)
上的索引可能有用,但可能不会。更好的解决方案是对p_email
和p_mobile
中的每一个都有不同的查询,单列索引支持每个查询。
谢谢,但你的SQL可能是错误的,不工作,请参阅oracle中的sql – hungudgm