Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/87.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
Oracle SQL-为什么此查询具有完整表扫描?_Sql_Oracle_Sql Execution Plan - Fatal编程技术网

Oracle SQL-为什么此查询具有完整表扫描?

Oracle SQL-为什么此查询具有完整表扫描?,sql,oracle,sql-execution-plan,Sql,Oracle,Sql Execution Plan,我对此查询有问题: SELECT * FROM customer_table PARTITION (p25062014) WHERE ( customer_table.username NOT IN ('user1','user2','user3') OR customer_table.username IS NULL ) AND (customer_table.ip NOT IN ('ip1','ip2','ip3') OR customer_ta

我对此查询有问题:

SELECT * FROM customer_table PARTITION (p25062014) WHERE ( customer_table.username NOT IN ('user1','user2','user3') OR customer_table.username IS NULL ) AND (customer_table.ip NOT IN ('ip1','ip2','ip3') OR customer_table.ip IS NULL ) AND ( customer_table."ACCOUNT DEVICE ID" NOT IN ('deviceId1','deviceId2','deviceId3') OR customer_table."ACCOUNT DEVICE ID" IS NULL ) 即使我已经为此表中的这些字段创建了索引,我仍然可以对该表进行完全的表访问:

CREATE INDEX customer_table_USERNAME ON customer_table (USERNAME) CREATE INDEX customer_table_DEVICE_ID ON customer_table ("ACCOUNT DEVICE ID") CREATE INDEX customer_table_IP ON customer_table (IP) 我怎样才能修好它?
谢谢。

不在where子句中通常不使用索引,因为索引没有多少好处。阅读细节。尽管该博客解释了为什么对not eqals比较忽略索引,但对not IN也同样有效。

如果您的表只有一行基数=1,那么对于我能想到的几乎任何查询,完整表扫描都是访问数据的最有效方法。嗨,Gordon,这个表现在几乎是空的,但很快它将包含每个分区大约200万条记录。需要修复吗?你面临的实际问题是什么?空值没有索引,不在中通常无法有效地使用索引,因此可能需要进行完整表或分区扫描,即使您有多行。你的统计数据是最新的吗?Oracle将根据统计信息和解析查询时认为表所处的状态选择计划;不在你的预期增长上,它对这一点一无所知。@Fabio。当您向表中添加更多数据并确保统计信息得到更新时,Oracle将选择更好的执行计划。我如何确保Oracle更新统计信息?我也可以更改查询以获得更好的性能,但我无法想象会出现不同的查询,我如何确保Oracle更新统计数据?我也可以更改查询以获得更好的性能,但我无法想象使用不同的querydbms_stat.gather_table_stats来保持统计信息的最新状态,请参见,但这不会使索引更有用。如果您不需要该数据,那么最好是减少select not select*中的列列表,并创建一个生成索引,其中包括select列表中的所有列以及where子句中使用的所有列。这使Oracle可以执行完整索引扫描而不是完整表扫描,而且速度会快得多。好的,我将指定列列表而不是,但如何创建?where子句已经存在,select列表是,如果您的查询是从mytable中选择a、b、c,其中d不在1,2中,e不在3,4中,则索引将是在mytabled、e、a、b、c上创建索引i_mytable,以便它可以用于检查where条件和收集结果,这样Oracle就不必读取该表。在本例中,列的顺序可能没有多大区别,因为无论列的顺序如何,完全索引扫描都是完全索引扫描。但是不要将表中的所有列都包含在索引中,这会使其无效!谢谢,我正在改进我的查询很多!但我不明白为什么这个查询是在完整表扫描中:我已经看到,如果我不包括ELAB TIME(数据库上的一个数字字段),访问就不在完整表扫描中,而如果我包括这个字段,它是完整的。 Plan SELECT STATEMENT ALL_ROWSCost: 2 Bytes: 965 Cardinality: 1 2 PARTITION RANGE SINGLE Cost: 2 Bytes: 965 Cardinality: 1 Partition #: 1 Partitions accessed #21 1 TABLE ACCESS FULL TABLE customer_table Cost: 2 Bytes: 965 Cardinality: 1 Partition #: 2 Partitions accessed #21