假设一个名为TABLE1的表中有10行,而TABLE2中的另一个表中有一百万行,如果我在这两个表上触发查询,如下所示:
Select * from TABLE1 where some_column = 'some_value';
和
Select * from TABLE2 where some_column = 'some_value';
我知道在这两种情况下我只会得到满足where子句的2行,那么获得结果的时间差异是多少。我不想在数字中得到任何确切的答案。我只是想知道两个查询会花费相同的时间,因为最终结果只有2行满足条件,或者所花费的时间取决于表中存在的总行数。
答案 0 :(得分:2)
我只是想知道两个查询会花费同一时间
此类问题的一般建议是:做基准测试。
在您的具体情况下,它在很大程度上取决于some_column
列上是否有索引。如果没有索引,数据库需要执行全表扫描,这意味着对所有行进行线性搜索。如果列上有索引,则查询不应该花费很多不同的时间。
如果怀疑是否完成了全表扫描或者是否可以将索引用于查询,则可以为SQL语句创建execution plan。
答案 1 :(得分:1)
这完全取决于表的索引方式。如果some_column上有索引,则两个查询所花费的时间大致相同(对于table2来说可能稍慢一些,因为table1的索引很可能由于较小的大小而驻留在内存中)。
如果表没有编入索引,查询2所用的时间可能会大得多,因为查询处理器必须扫描整个1.000.000行才能找到满足WHERE子句的行。
答案 2 :(得分:0)
更准确地说,查询运行的速度取决于所使用的索引。 在大多数(琐碎的)情况下,你将在你的桌子上设置一个主键,这将导致最简单的索引情况,你的表中的每一行都有一个唯一的数字,然后它可以被比较,这就是占用时间的东西。在这种情况下,所花费的时间取决于表中的行数,但当您在表上有不同类型的索引时,这可能会有很大差异(是的,可以有多个;)
进一步阅读indexes
答案 3 :(得分:0)
根据建议,做基准测试。一个简单的 - 一个包含10行和300k行的2个表 - 向我们显示,如果您的条件具有高度选择性,则没有太大的区别(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
答案 4 :(得分:0)
大多数其他答案都将索引视为影响查询性能。虽然这是一个很大的问题,但它不仅仅是索引会影响查询所用的时间长度。
在其他五个案例中,没有所有索引:
分区表:如果在some_column
上对一个表进行了分区,则Oracle可能只扫描单个分区而不是整个表。这称为分区修剪 - Oracle消除了它知道赢得的分区,并且不包含查询中所需的任何数据。请参阅http://docs.oracle.com/cd/B10501_01/server.920/a96524/c12parti.htm#429785
并行全表扫描:如果启用了并行查询,Oracle可以动态地将表分解为粒度,并行进程可以扫描每个表以查找您正在寻找的值。请参阅http://docs.oracle.com/cd/A97630_01/server.920/a96524/c20paral.htm#6346
物理磁盘上的数据位置:不同的物理存储系统具有不同的性能特征。 DBA可以将某些历史数据表移动到相对缓慢,廉价的存储上,而其他表明确地移动到相对昂贵的快速存储中。
Oracle缓存:表的数据已经可以在内存中,由Oracle自动或手动固定。这肯定会影响表现。
表&#34;宽度&#34;。宽表(包含许多列)将比包含较少列的窄表扫描更慢。