Когда Oracle индексирует пустые значения столбцов?

Так или иначе, я следовал за своим рабочим процессом на недавнем ответвлении, и когда я пытался объединить его назад с ведущим устройством, все это пошло к черту. Были тонны конфликтов с вещами, которые не должны были иметь значения. Конфликты просто не имели никакого смысла мне. Это взяло меня день для улаживания всего, и в конечном счете достигло высшей точки в принудительном нажатии удаленному ведущему устройству, так как у моего локального ведущего устройства есть все разрешенные конфликты, но удаленный все еще не был счастлив.

ни В Вашем партнере, ни в Ваши предложенные рабочие процессы должен Вы сталкиваться с конфликтами, которые не имели смысла. Даже если бы Вы имели, если Вы следуете за предложенными рабочими процессами тогда после разрешения, то 'принудительное' нажатие не должно требоваться. Это предполагает, что Вы на самом деле не объединили ответвление, к которому Вы продвигали, но должны были продвинуть ответвление, которое не было потомком удаленной подсказки.

я думаю, что необходимо посмотреть тщательно на то, что произошло. Кто-то еще мог иметь (сознательно, или не) перемотал удаленное основное ответвление между Вашим созданием локального ответвления и точкой, в которой Вы попытались объединить его назад в локальное ответвление?

По сравнению со многими другими системами управления версиями я нашел, что использование Мерзавца включает меньше борьбы с инструментом и позволяет Вам взяться за работу над проблемами, которые фундаментальны для Ваших исходных потоков. Мерзавец не выполняет волшебство, таким образом конфликтуя конфликты причины изменений, но оно должно облегчить делать вещь записи своим отслеживанием происхождения фиксации.

12
задан Thilo 5 August 2009 в 01:51
поделиться

3 ответа

Если какой-либо индексированный столбец содержит ненулевое значение, эта строка будет проиндексирована. Как вы можете видеть в следующем примере, только одна строка не индексируется, и эта строка имеет NULL в обоих индексированных столбцах. Вы также можете видеть, что Oracle определенно индексирует строку, когда ведущий столбец индекса имеет значение NULL.

SQL> create table big_table as
  2       select object_id as pk_col
  3               , object_name as col_1
  4               , object_name as col_2
  5  from all_objects
  6  /

Table created.

SQL> select count(*) from big_table
  2  /

  COUNT(*)
----------
     69238

SQL> insert into big_table values (9999990, null, null)
  2  /

1 row created.

SQL> insert into big_table values (9999991, 'NEW COL 1', null)
  2  /

1 row created.

SQL> insert into big_table values (9999992, null, 'NEW COL 2')
  2  /

1 row created.

SQL> select count(*) from big_table
  2  /

  COUNT(*)
----------
     69241

SQL> create index big_i on big_table(col_1, col_2)
  2  /

Index created.

SQL> exec dbms_stats.gather_table_stats(user, 'BIG_TABLE', cascade=>TRUE)

PL/SQL procedure successfully completed.


SQL> select num_rows from user_indexes where index_name = 'BIG_I'
  2  /

  NUM_ROWS
----------
     69240

SQL> set autotrace traceonly exp
SQL>
SQL> select pk_col from big_table
  2  where col_1 = 'NEW COL 1'
  3  /

Execution Plan
----------------------------------------------------------
Plan hash value: 1387873879

-----------------------------------------------------------------------------------------
| Id  | Operation                   | Name      | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |           |     2 |    60 |     4   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| BIG_TABLE |     2 |    60 |     4   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN          | BIG_I     |     2 |       |     3   (0)| 00:00:01 |
-----------------------------------------------------------------------------------------

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

   2 - access("COL_1"='NEW COL 1')

SQL> select pk_col from big_table
  2  where col_2 = 'NEW COL 2'
  3  /

Execution Plan
----------------------------------------------------------
Plan hash value: 3993303771

-------------------------------------------------------------------------------
| Id  | Operation         | Name      | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |           |     2 |    60 |   176   (1)| 00:00:03 |
|*  1 |  TABLE ACCESS FULL| BIG_TABLE |     2 |    60 |   176   (1)| 00:00:03 |
-------------------------------------------------------------------------------

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

   1 - filter("COL_2"='NEW COL 2')

SQL> select pk_col from big_table
  2  where col_1 is null
  3  and col_2 = 'NEW COL 2'
  4  /

Execution Plan
----------------------------------------------------------
Plan hash value: 1387873879

-----------------------------------------------------------------------------------------
| Id  | Operation                   | Name      | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |           |     1 |    53 |     4   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| BIG_TABLE |     1 |    53 |     4   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN          | BIG_I     |     2 |       |     3   (0)| 00:00:01 |
-----------------------------------------------------------------------------------------

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

   2 - access("COL_1" IS NULL AND "COL_2"='NEW COL 2')
       filter("COL_2"='NEW COL 2')

SQL> select pk_col from big_table
  2  where col_1 is null
  3  and col_2 is null
  4  /

Execution Plan
----------------------------------------------------------
Plan hash value: 3993303771

-------------------------------------------------------------------------------
| Id  | Operation         | Name      | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |           |     1 |    53 |   176   (1)| 00:00:03 |
|*  1 |  TABLE ACCESS FULL| BIG_TABLE |     1 |    53 |   176   (1)| 00:00:03 |
-------------------------------------------------------------------------------

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

   1 - filter("COL_1" IS NULL AND "COL_2" IS NULL)

SQL>

Этот пример работает в Oracle 11.1.0.6. Но я почти уверен, что это верно для всех версий.

25
ответ дан 2 December 2019 в 03:49
поделиться

И в дополнение к ответу APC: если вы хотите проиндексировать значение NULL, вы можете добавить в индекс постоянное выражение.

Пример:

SQL> select * from v$version where rownum = 1
  2  /

BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bi

1 rij is geselecteerd.

SQL> create table t (id,status,fill)
  2  as
  3   select level
  4        , nullif(ceil((level-1)/1000),0)
  5        , lpad('*',1000,'*')
  6     from dual
  7  connect by level <= 10000
  8  /

Tabel is aangemaakt.

SQL> select status
  2       , count(*)
  3    from t
  4   group by status
  5  /

    STATUS   COUNT(*)
---------- ----------
         1       1000
         2       1000
         3       1000
         4       1000
         5       1000
         6       1000
         7       1000
         8       1000
         9       1000
        10        999
                    1

11 rijen zijn geselecteerd.

SQL> create index i_status on t(status)
  2  /

Index is aangemaakt.

SQL> exec dbms_stats.gather_table_stats(user,'t',cascade=>true)

PL/SQL-procedure is geslaagd.

SQL> set autotrace traceonly
SQL> select *
  2    from t
  3   where status is null
  4  /

1 rij is geselecteerd.


Uitvoeringspan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=ALL_ROWS (Cost=201 Card=1 Bytes=1007)
   1    0   TABLE ACCESS (FULL) OF 'T' (TABLE) (Cost=201 Card=1 Bytes=1007)


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

Обратите внимание на полное сканирование таблицы и 364 согласованных получения.

SQL> set autotrace off
SQL> create index i_status2 on t(status,1)
  2  /

Index is aangemaakt.

SQL> set autotrace traceonly
SQL> select *
  2    from t
  3   where status is null
  4  /

1 rij is geselecteerd.


Uitvoeringspan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=ALL_ROWS (Cost=1 Card=1 Bytes=1007)
   1    0   TABLE ACCESS (BY INDEX ROWID) OF 'T' (TABLE) (Cost=1 Card=1 Bytes=1007)
   2    1     INDEX (RANGE SCAN) OF 'I_STATUS2' (INDEX) (Cost=1 Card=1)


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

И теперь он использует индекс и имеет только 3 согласованных получения.

С уважением, Роб.

11
ответ дан 2 December 2019 в 03:49
поделиться

В дополнение к ответу APC , NULLS индексируются в индексах битовой карты.

3
ответ дан 2 December 2019 в 03:49
поделиться
Другие вопросы по тегам:

Похожие вопросы: