Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/10.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/cmake/2.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_Database Indexes - Fatal编程技术网

Sql 不使用索引进行分组

Sql 不使用索引进行分组,sql,oracle,database-indexes,Sql,Oracle,Database Indexes,有一个表有交易,其行数为2.2亿,其中一列为交易对手。该列已编入索引。如果我运行普通查询,如: select * from <table> where counterparty = 'X' 第二 我将做一个有根据的猜测,并说对手方被定义为可为空的列。因此,Oracle不能仅依靠索引来生成您的分组依据查询的结果,因为结果中需要包含空值,但(Oracle)索引不包含空值。考虑到这一点,全表扫描是有意义的 如果没有充分的理由使交易对手可以为空,请继续并使其不为空。然后,执行计划

有一个表有交易,其行数为2.2亿,其中一列为
交易对手
。该列已编入索引。如果我运行普通查询,如:

select * 
  from <table> 
 where counterparty = 'X'
第二
我将做一个有根据的猜测,并说
对手方
被定义为可为空的列。因此,Oracle不能仅依靠索引来生成您的
分组依据
查询的结果,因为结果中需要包含空值,但(Oracle)索引不包含空值。考虑到这一点,全表扫描是有意义的

如果没有充分的理由使
交易对手
可以为空,请继续并使其
不为空
。然后,执行计划应更改为按预期使用索引

或者,如果您不能进行更改,但不关心此特定查询的空值,则可以调整查询以显式筛选空值。这也会产生更好的执行计划

select counterparty, count(*)
  from tbl
 where counterparty is not null -- add this filter
 group by counterparty

注意:我不是Sybase专家,但我假设索引包含空值。Oracle索引不包含空值。这就解释了两个数据库之间执行计划的差异。

交易对手是可空列吗?感谢您的回复,是的,它是可空列。。但它是拇指规则group by不会用于所有可空列吗?或者这取决于乐观主义者。非常感谢,这确实有帮助。在我添加NOTNULL之后,它开始使用索引。很抱歉,但我还有一个问题:这是一条经验法则吗?若一列为null,则该列上的GROUPBY将不使用索引?我在另一个没有“NOTNULL”约束的列上使用了相同的查询,但该列上的group by使用了索引(尽管不同)。。所以我有点困惑,乐观主义者是如何工作的。不能不看这个问题就说。我的猜测是,查询必须有一些过滤子句,隐式地使空值无法返回。如果是这样的话,Oracle将能够利用该索引。但是,是的,我想说的是,经验法则是,如果您有一个按索引列分组的查询,其中查询结果可能会返回该列的null值,那么不要期望优化器使用该索引。
Plan hash value: 350128866

| Id  | Operation                   | Name                | Rows  | Bytes | Cost (%CPU)| Time     |
|   0 | SELECT STATEMENT            |                     |  2209 |  1469K|   914   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| FXCASHTRADE         |  2209 |  1469K|   914   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN          | SCB_FXCASHTRADE_002 |  2209 |       |    11   (0)| 00:00:01 |


Predicate Information (identified by operation id):

    2 - access("COUNTERPARTY"='test')
> Plan hash value: 2920872612

| Id  | Operation          | Name        | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |
|   0 | SELECT STATEMENT   |             |   100K|  2151K|       |  6558K  (1)| 00:00:38 |
|   1 |  HASH GROUP BY     |             |   100K|  2151K|  6780M|  6558K  (1)| 00:00:38 |
|   2 |   TABLE ACCESS FULL| FXCASHTRADE |   221M|  4643M|       |  6034K  (1)| 00:00:35 |
select counterparty, count(*)
  from tbl
 where counterparty is not null -- add this filter
 group by counterparty