SQL查询给出结果所花费的时间是否取决于表中的总行数,还是取决于作为结果的最终行数?

SQL查询给出结果所花费的时间是否取决于表中的总行数,还是取决于作为结果的最终行数?,sql,oracle,Sql,Oracle,假设名为TABLE1的表中有10行,而TABLE2的另一个表中有100万行,如果我对这两个表进行如下查询: Select * from TABLE1 where some_column = 'some_value'; 及 我知道在这两种情况下,我只会得到满足where子句的2行,那么得到结果的时间差是多少。我不想从数字中得到任何确切的答案。我只想知道,两个查询将花费相同的时间,因为最终结果只有2行满足条件,或者所花费的时间是否取决于表中的行总数。这完全取决于表的索引方式。如果某个_列上有一个索

假设名为TABLE1的表中有10行,而TABLE2的另一个表中有100万行,如果我对这两个表进行如下查询:

Select * from TABLE1 where some_column = 'some_value';


我知道在这两种情况下,我只会得到满足where子句的2行,那么得到结果的时间差是多少。我不想从数字中得到任何确切的答案。我只想知道,两个查询将花费相同的时间,因为最终结果只有2行满足条件,或者所花费的时间是否取决于表中的行总数。

这完全取决于表的索引方式。如果某个_列上有一个索引,则两个查询所用的时间大致相同(表2可能会稍微慢一点,因为表1的索引很可能会驻留在内存中,因为其大小较小)


如果表没有索引,查询2所需的时间可能会大得多,因为查询处理器必须扫描整个1.000.000行以找到满足WHERE子句的行。

更准确地说,查询运行的速度取决于所使用的索引。 在大多数(琐碎的)情况下,您会在表上设置一个主键,这导致了最简单的索引情况,表中的每一行都有一个唯一的数字,然后通过它进行比较,这就占用了时间。在这种情况下,所花费的时间取决于表中的行数,但当表上有不同类型的索引时,所花费的时间可能会有很大差异(是的,可以有多个;)

进一步阅读

我只是想知道,两个查询是否需要相同的时间

针对此类问题的一般建议是:进行基准测试

  • 创建一个测试数据库,其中包含稍后在生产系统中所需的数据量(您可以使用简单的PL/SQL脚本或支持数据库连接的任何其他编程环境轻松完成此操作)
  • 然后,创建一个小型应用程序(理想情况下是在稍后执行查询的同一编程环境中),用于执行查询(理想情况下是多次)并测量所需时间。根据结果,您可以采取进一步的措施
在您的特定情况下,这在很大程度上取决于
some\u列
列上是否有索引。如果没有索引,数据库需要进行全表扫描,这意味着对所有行进行线性搜索。如果列上有索引,则查询所用的时间应该不会有太大差异


如果对是否完成完整表扫描或是否可以使用索引进行查询有疑问,可以为SQL语句创建索引。

按照建议,进行基准测试。一个简单的1-2个表,包含10行和300k行-向我们显示,如果您的条件是高度选择性的,则没有巨大的差异(2对4个数据库块通过查询读取)

15:22:14 HR@sandbox> ed
Wrote file S:\spool\sandbox\BUFFER_HR_42.sql

  1  create table table1 as
  2  select decode(rownum, 5, 6, 10, 6, mod(rownum, 5)) as value from dual
  3* connect by rownum <= 10
15:22:26 HR@sandbox> /

Table created.

Elapsed: 00:00:00.16
15:23:52 HR@sandbox> ed
Wrote file S:\spool\sandbox\BUFFER_HR_42.sql

  1   create table table2 as
  2   select decode(rownum, 1e3, 6, 5e4, 6, mod(rownum, 5)) as value from dual
  3*  connect by rownum <= 3e5
15:23:59 HR@sandbox> /

Table created.

Elapsed: 00:00:03.10
15:24:03 HR@sandbox> create index ix_t2_val on table2(value);

Index created.

Elapsed: 00:00:02.11
15:24:12 HR@sandbox> create index ix_t1_val on table1(value);

Index created.

Elapsed: 00:00:00.05
15:24:16 HR@sandbox> exec dbms_stats.gather_table_stats('hr','table1');

PL/SQL procedure successfully completed.

Elapsed: 00:00:00.93
15:25:14 HR@sandbox> exec dbms_stats.gather_table_stats('hr','table2');

PL/SQL procedure successfully completed.

Elapsed: 00:00:02.19
15:25:18 HR@sandbox> select /*+index(table1 ix_t1_val)*/ * from table1 where value = 6;

Elapsed: 00:00:00.01

Execution Plan
----------------------------------------------------------
Plan hash value: 1719610244

------------------------------------------------------------------------------
| Id  | Operation        | Name      | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------
|   0 | SELECT STATEMENT |           |     2 |     6 |     1   (0)| 00:00:01 |
|*  1 |  INDEX RANGE SCAN| IX_T1_VAL |     2 |     6 |     1   (0)| 00:00:01 |
------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - access("VALUE"=6)


Statistics
----------------------------------------------------------
          1  recursive calls
          0  db block gets
          2  consistent gets
          0  physical reads
          0  redo size
        369  bytes sent via SQL*Net to client
        363  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          2  rows processed

15:25:34 HR@sandbox> select /*+index(table1 ix_t2_val)*/ * from table2 where value = 6;

Elapsed: 00:00:00.02

Execution Plan
----------------------------------------------------------
Plan hash value: 4026617716

------------------------------------------------------------------------------
| Id  | Operation        | Name      | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------
|   0 | SELECT STATEMENT |           | 50000 |   146K|    99   (0)| 00:00:02 |
|*  1 |  INDEX RANGE SCAN| IX_T2_VAL | 50000 |   146K|    99   (0)| 00:00:02 |
------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - access("VALUE"=6)


Statistics
----------------------------------------------------------
          1  recursive calls
          0  db block gets
          4  consistent gets
          1  physical reads
          0  redo size
        369  bytes sent via SQL*Net to client
        363  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          2  rows processed
15:22:14HR@sandbox>
写入文件S:\spool\sandbox\BUFFER\u HR\u 42.sql
1将表1创建为
2选择decode(rownum,5,6,10,6,mod(rownum,5))作为来自dual的值
3*通过rownum连接/
表已创建。
已过时间:00:00:00.16
15:23:52 HR@sandbox>
写入文件S:\spool\sandbox\BUFFER\u HR\u 42.sql
1将表2创建为
2选择decode(rownum,1e3,6,5e4,6,mod(rownum,5))作为来自dual的值
3*通过rownum连接/
表已创建。
已过时间:00:00:03.10
15:24:03 HR@sandbox>在表2上创建索引ix_t2_val(值);
已创建索引。
已过时间:00:00:02.11
15:24:12 HR@sandbox>在表1上创建索引ix_t1_val(值);
已创建索引。
已过时间:00:00:00.05
15:24:16 HR@sandbox>exec dbms_stats.gather_table_stats('hr','table1');
PL/SQL过程已成功完成。
已过时间:00:00:00.93
15:25:14 HR@sandbox>exec dbms_stats.gather_table_stats('hr','table2');
PL/SQL过程已成功完成。
已过时间:00:00:02.19
15:25:18 HR@sandbox>从表1中选择/*+索引(表1 ix_t1_val)*/*值=6;
已过时间:00:00:00.01
执行计划
----------------------------------------------------------
计划哈希值:1719610244
------------------------------------------------------------------------------
|Id |操作|名称|行|字节|成本(%CPU)|时间|
------------------------------------------------------------------------------
|0 | SELECT语句| 2 | 6 | 1(0)| 00:00:01|
|*1 |索引范围扫描| IX|u T1|u VAL | 2 | 6 | 1(0)| 00:00:01|
------------------------------------------------------------------------------
谓词信息(由操作id标识):
---------------------------------------------------
1-访问(“值”=6)
统计
----------------------------------------------------------
1递归调用
0 db块获取
2个一致的GET
0次物理读取
0重做大小
369字节通过SQL*Net发送到客户端
通过SQL*Net从客户端接收363字节
与客户端之间的2次SQL*Net往返
0排序(内存)
0排序(磁盘)
已处理2行
15:25:34 HR@sandbox>从表2中选择/*+索引(表1 ix_t2_val)*/*值=6;
已过时间:00:00:00.02
执行计划
----------------------------------------------------------
计划哈希值:4026617716
------------------------------------------------------------------------------
|Id |操作|名称|行|字节|成本(%CPU)|时间|
------------------------------------------------------------------------------
|0 | SELECT语句| 50000 | 146K | 99(0)| 00:00:02|
|*1 |索引范围扫描| IX|T2|u VAL | 50000 | 146K | 99(0)| 00:00:02|
------------------------------------------------------------------------------
15:22:14 HR@sandbox> ed
Wrote file S:\spool\sandbox\BUFFER_HR_42.sql

  1  create table table1 as
  2  select decode(rownum, 5, 6, 10, 6, mod(rownum, 5)) as value from dual
  3* connect by rownum <= 10
15:22:26 HR@sandbox> /

Table created.

Elapsed: 00:00:00.16
15:23:52 HR@sandbox> ed
Wrote file S:\spool\sandbox\BUFFER_HR_42.sql

  1   create table table2 as
  2   select decode(rownum, 1e3, 6, 5e4, 6, mod(rownum, 5)) as value from dual
  3*  connect by rownum <= 3e5
15:23:59 HR@sandbox> /

Table created.

Elapsed: 00:00:03.10
15:24:03 HR@sandbox> create index ix_t2_val on table2(value);

Index created.

Elapsed: 00:00:02.11
15:24:12 HR@sandbox> create index ix_t1_val on table1(value);

Index created.

Elapsed: 00:00:00.05
15:24:16 HR@sandbox> exec dbms_stats.gather_table_stats('hr','table1');

PL/SQL procedure successfully completed.

Elapsed: 00:00:00.93
15:25:14 HR@sandbox> exec dbms_stats.gather_table_stats('hr','table2');

PL/SQL procedure successfully completed.

Elapsed: 00:00:02.19
15:25:18 HR@sandbox> select /*+index(table1 ix_t1_val)*/ * from table1 where value = 6;

Elapsed: 00:00:00.01

Execution Plan
----------------------------------------------------------
Plan hash value: 1719610244

------------------------------------------------------------------------------
| Id  | Operation        | Name      | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------
|   0 | SELECT STATEMENT |           |     2 |     6 |     1   (0)| 00:00:01 |
|*  1 |  INDEX RANGE SCAN| IX_T1_VAL |     2 |     6 |     1   (0)| 00:00:01 |
------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - access("VALUE"=6)


Statistics
----------------------------------------------------------
          1  recursive calls
          0  db block gets
          2  consistent gets
          0  physical reads
          0  redo size
        369  bytes sent via SQL*Net to client
        363  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          2  rows processed

15:25:34 HR@sandbox> select /*+index(table1 ix_t2_val)*/ * from table2 where value = 6;

Elapsed: 00:00:00.02

Execution Plan
----------------------------------------------------------
Plan hash value: 4026617716

------------------------------------------------------------------------------
| Id  | Operation        | Name      | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------
|   0 | SELECT STATEMENT |           | 50000 |   146K|    99   (0)| 00:00:02 |
|*  1 |  INDEX RANGE SCAN| IX_T2_VAL | 50000 |   146K|    99   (0)| 00:00:02 |
------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - access("VALUE"=6)


Statistics
----------------------------------------------------------
          1  recursive calls
          0  db block gets
          4  consistent gets
          1  physical reads
          0  redo size
        369  bytes sent via SQL*Net to client
        363  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          2  rows processed