此表提供有关房地产的信息。 “类型”列包含值“公寓”,“房屋”,“联排别墅”或“别墅”。每种类型的条目数大约是表中条目总数的25%。
表名列名称数据类型 RealEstate ID DEC(10) 类型VARCHAR(40) 价格DEC(10,2) 尺寸DEC(4) 典型的查询要求给定类型的所有房地产: 选择ID 来自RealEstate 其中Type ='House' 为此表定义了两个索引。第一个索引是为“ID”列定义的,第二个索引是为“Type”列定义的。这个查询相对于条目数n和结果集大小的时间复杂度m ??
时间复杂度为O(log(n)+ m)或O(n)??
答案 0 :(得分:2)
这非常粗略地说是一种推测:
复杂性应该是O(m),因为由于存在索引,所以
数据库引擎可以找到/找到与Type = 'House'
匹配的记录
在恒定的时间。所以在这里花费时间就是处理这个问题
匹配计数为m的记录(例如,读取它们并返回
他们到来电者)。所以复杂度是O(m)因为处理
与返回的记录数成正比。
但是从较低的层面来看,我猜这一切都取决于许多其他事情:
如果你的索引维护得很好(没有碎片),如果记录位置很好的话
在磁盘上(例如顺序地)等等。因此很难给出直接/简单的
大O公式。
答案 1 :(得分:0)
时间复杂度可能是O(n)。
这个问题是另一种问“这个查询会使用索引扫描还是全表扫描?”的方法。通常,索引范围扫描在查找一小部分行时效果更好。而且,通常,在查找大部分行时,全表扫描效果会更好。
没有一个“神奇数字”。但根据我的经验,使用任何显着大小的表格,25%绝对是全表扫描区域。
这个决定取决于很多因素:缓存,多块读取计数,物理存储,统计(对象和系统),集群因素(磁盘上存储的行数有多好 - 因为Oracle一次只检索一个数据块查询可能需要读取100%的块来读取1%的数据)等等。
代码示例
这是一个简单的示例演示全表扫描。请注意,我使用了100000行。如果问题是关于一个只有少量行的表而不是时间复杂度是无关紧要的,因为恒定开销将比算法更重要。
create table RealEstate
(
ID DEC(10),
Type VARCHAR(40),
Price DEC(10,2),
the_Size DEC(4)
);
create index RealEstate_idx on RealEstate(type);
insert into RealEstate
select level, decode(mod(level, 4), 0, 'Apartment', 1, 'House', 2, 'Townhouse', 3, 'Villa') , 100, 100
from dual connect by level <= 100000;
begin
dbms_stats.gather_table_stats(user, 'realestate');
end;
/
执行计划
请注意TABLE ACCESS FULL
。
explain plan for select * from RealEstate where type = 'House';
select * from table(dbms_xplan.display);
Plan hash value: 4238863598
--------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 25000 | 463K| 103 (1)| 00:00:01 |
|* 1 | TABLE ACCESS FULL| REALESTATE | 25000 | 463K| 103 (1)| 00:00:01 |
--------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("TYPE"='House')