我试图从包含数百万条目的表中获取计数。我的查询看起来像这样:
Select count(*)
from Users
where status = 'A' and office_id = '000111' and user_type = 'C'
状态可以是A或C,用户类型可以是C或R. 状态,Office_id和User_type是字符串
结果有大约1000万行,并且花费了大量时间。我只想要总数。
如果有人能告诉我为什么花了这么多时间,并且解决方法(如果有的话),我将不胜感激。
如果需要更多细节,请告诉我。
数据库引擎是Oracle 11g
编辑:我添加了所有三个列的索引。仍然没有改善。还尝试了以下查询,但它总是在不检查条件的情况下返回表中的总计数。
SELECT COUNT(office_id_key)
FROM Users
WHERE EXISTS (SELECT * FROM Users WHERE status = 'A' AND office_id = '000111' AND user_type = 'C')
答案 0 :(得分:4)
为什么不只是简单地在age
和place
的表格上创建索引,这样您的搜索速度就会快于扫描整个表格中的这些值。
CREATE INDEX age_index ON Employee(age);
CREATE INDEX place_index ON Employee(place);
这应该加快这个过程。
基于“查询更改”修改
CREATE INDEX status_index ON Users(status);
CREATE INDEX office_id_index ON Users(office_id);
CREATE INDEX user_type_index ON Users(user_type);
答案 1 :(得分:2)
您希望在Users
表上创建以下多列索引以改进查询:
(office_id, status, user_type)
数据库可以使用"覆盖"索引为COUNT(*)
。由于基数,使用该顺序的列创建索引。
答案 2 :(得分:0)
添加索引后,我认为改变存在的位置和子查询也可能有所帮助。
Edit2:删除存在,因为它返回所有有效的,通常子查询有多个连接,但我想一个表的情况返回所有true。我读到,当count只有一个表而没有where子句时,count被优化为类似于exists的行为,因此我将结果视为表。希望这会有同样快速的结果。
select count(1) from
(select 1 from Employee where age = '25' and place = 'bricksgate')
编辑:当您使用'where exists'时,数据库服务器不会将数据加载到内存中,也会利用索引,因为您将从索引中读取值而不进行昂贵的表查找。您可能还希望将count(*)更改为count(place) - 这样它也会将字段限制为索引字段。
在原始查询中,您的数据正在进行表查找,然后将它们加载到内存中以便计算。
答案 3 :(得分:-1)
count(1)比count(*)
工作得更快