Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 如何理解避免全表扫描_Sql_Oracle_Query Optimization_Full Table Scan - Fatal编程技术网

Sql 如何理解避免全表扫描

Sql 如何理解避免全表扫描,sql,oracle,query-optimization,full-table-scan,Sql,Oracle,Query Optimization,Full Table Scan,我有一个负责存储日志的表。 DDL是这样的: CREATE TABLE LOG( "ID_LOG" NUMBER(12,0) NOT NULL ENABLE, "DATA" DATE NOT NULL ENABLE, "OPERATOR_CODE" VARCHAR2(20 BYTE), "STRUCTURE_CODE" VARCHAR2(20 BYTE), CONSTRAINT "LOG_PK" PRIMARY KEY ("ID_LOG")

我有一个负责存储日志的表。 DDL是这样的:

CREATE TABLE LOG(
    "ID_LOG" NUMBER(12,0) NOT NULL ENABLE, 
    "DATA" DATE NOT NULL ENABLE, 
    "OPERATOR_CODE" VARCHAR2(20 BYTE), 
    "STRUCTURE_CODE" VARCHAR2(20 BYTE), 

     CONSTRAINT "LOG_PK" PRIMARY KEY ("ID_LOG")
 );
根据这两个指数:

CREATE INDEX STRUCTURE_CODE ON LOG ("OPERATOR_CODE");

CREATE INDEX LOG_01 ON LOG ("STRUCTURE_CODE", "DATA") ;
但此查询会生成完整的表扫描:

SELECT log.data AS data1, 
       OPERATOR_CODE,
       STRUCTURE_CODE
  FROM log
 WHERE data BETWEEN to_date('03/03/2008', 'DD-MM-YYYY')
                AND to_date('08/03/2015', 'DD-MM-YYYY')
   AND STRUCTURE_CODE = '1601';
为什么我总是在列
数据
结构\u代码
上看到
全表扫描


(我也尝试过为
结构\u code
数据创建两个不同的索引,但我总是进行完整的表扫描)

您对新索引和表运行了统计信息吗

该表中有多少数据,该查询可能返回的数据百分比是多少?有时,对于小表或返回大量数据的查询,完整表扫描更好

  • 那张桌子上有多少行
  • 这个查询返回了多少
  • 请包括解释计划
  • 如果加载表并进行完整表扫描(FTS)比使用索引便宜(IO成本),则会加载表并进行FTS。[基本上和Necreaux说的一样]

    如果表很小,或者预期的结果集大小很大,则可能会发生这种情况

    什么是小的?如果表小于,FTS几乎总是会发生。在这种情况下,通常可以通过一次大读取将表加载到内存中。这并不总是一个问题,检查解释计划中的IO成本

    什么是大的?如果表相当大,并且您将返回大部分,那么在几个大IO调用中读取整个表要比进行一些索引读取然后在表周围进行大量小IO调用便宜


    < Blind >从您的查询中猜出(没有解释计划结果),我认为它首先会考虑索引范围扫描(LogLog01),接着是RoWID的表访问(以获取运算符代码,因为它不在索引中),但是或者它决定您的表太小,或者从该日期范围/结构代码返回的行太多,因此在表中滚动比较便宜(按IO成本计算)。

    主表中有多少行,以及此
    SELECT
    查询返回多少行?正如@Necreaux所说,收集指数的数据。你的日期范围很广(2008年至2015年),因此指数不太可能有足够的选择性。