【问题标题】:Search time complexity of this sql query此 sql 查询的搜索时间复杂度
【发布时间】:2014-12-30 23:26:47
【问题描述】:

此表提供有关房地产的信息。 “类型”列包含值“公寓”、“房屋”、“联排别墅”或“别墅”。每种类型的条目数约为表中条目总数的 25%。

表名列名数据类型 房地产 ID DEC(10) 类型 VARCHAR(40) 价格 DEC(10,2) 尺寸 DEC(4) 一个典型的查询询问给定类型的所有不动产: 选择身份证 来自房地产 其中类型 = '房子' 为此表定义了两个索引。第一个索引是为“ID”列定义的,第二个索引是为“Type”列定义的。这个查询相对于条目数 n 和结果集大小 m 的时间复杂度是多少??

时间复杂度会是O(log(n)+m)还是O(n)??

【问题讨论】:

    标签: sql oracle big-o time-complexity


    【解决方案1】:

    这是非常粗略的说法,在某种程度上是一种推测:

    复杂度应该是 O(m),因为由于存在索引,
    数据库引擎可以找到/定位匹配Type = 'House'的记录
    在恒定时间内。所以这里需要时间的只是处理
    匹配计数为 m 的记录(例如读取它们并返回
    他们给来电者)。所以复杂度是 O(m) 因为处理
    与返回的记录数成正比。

    但是从较低的层次来看,我想这也取决于许多其他的事情:
    如果您的索引维护良好(没有碎片化),如果记录位置良好
    在磁盘上(例如顺序)等等。所以很难给出直接/简单的
    大O公式。

    【讨论】:

      【解决方案2】:

      时间复杂度可能是 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')
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-02-08
        • 2022-12-03
        • 1970-01-01
        • 2017-09-17
        • 2011-03-04
        • 1970-01-01
        相关资源
        最近更新 更多