Какой самый быстрый способ найти, если столбец имеет хотя бы одно значение NULL в базе данных ORACLE? - PullRequest
0 голосов
/ 27 февраля 2020

select 1 from MYTABLE where MYDATE is null AND ROWNUM = 1;

В моих таблицах столько значений, что запрос никогда не заканчивается ...

Я пытаюсь найти, есть ли в таблице хотя бы одно значение NULL в определенном столбце.

ROWNUM = 1 заставляет Oracle остановиться на первом действительном результате? Или это будет go думал весь стол? Как сделать это быстрее?

Ответы [ 5 ]

2 голосов
/ 27 февраля 2020

Если ваша таблица имеет одно нулевое значение, скрывающееся среди миллиарда строк, для ее обнаружения обычно требуется полное сканирование всей таблицы (остановка при ее обнаружении).

Это верно для ответов, использующих различные SQL формы, ответы, основанные на сборе статистики, и ответы, основанные на попытке применить ограничение NOT NULL к столбцу.

После того, как вы используете ROWNUM=1, чтобы убедиться, что вы остановились после первого нулевое значение, что вы можете попытаться сделать, это:

  • Используйте подсказку /*+ PARALLEL */, чтобы сделать полное сканирование go быстрее
  • Если вы ' собрав статистику на столе, используя 100% выборку, вы можете посмотреть в ALL_TAB_COLUMNS.NUM_NULLS. Это не избавляет от необходимости полного сканирования таблицы, оно просто позволяет избежать его, используя тот, который был выполнен при сборе статистики. Недостатком этого подхода является то, что статистика может быть неактуальной.
  • Если в интересующем столбце есть индекс И в столбце NOT NULL в той же таблице есть индекс, вы можете попробуйте SELECT COUNT(INDEXED_COLUMN_NAME) FROM TABLE и SELECT COUNT(INDEXED_NOT_NULL_COLUMN) FROM TABLE и вычтите их. Это использует тот факт, что значения null не будут отображаться в индексе, поэтому значения будут другими. Это будет быстрее, потому что индексы будут меньше и, следовательно, быстрее для чтения, чем полная таблица.

Если это то, что вам нужно будет делать часто, вы можете создать индекс на основе функции, чтобы ускорить это поиск в будущем:

CREATE index_name ON table_name ( NVL(column_name, impossible_value_for_column) );

например,

CREATE index_name ON table_name ( NVL(column_name, -99999999) );

Тогда

SELECT * FROM table_name 
WHERE NVL(column_name, -99999999) = -99999999 
AND column_name IS NULL  -- in case your "impossible value" really wasn't impossible;
1 голос
/ 27 февраля 2020

Если вы добавите предикат rownum = 1 в свой запрос, Oracle прекратит поиск после того, как будет найдена первая строка.

Если ваш запрос занимает много времени, это потому, что не было ни одной строки, которая соответствовала ваши другие предикаты до сих пор.

Чтобы ускорить ваш запрос, предполагая, что это регулярно выполняемый запрос, а не разовый запрос, вы всегда можете добавить индекс (mydate, 1) - который обеспечит строки с Нулевой mydate будет сохранен в индексе (обратите внимание на наличие константы, которая гарантирует, что все столбцы в индексе не будут все нулевыми).

1 голос
/ 27 февраля 2020

Вы даже можете использовать для выдачи DDL, пытаясь добавить ограничение NOT NULL для этого отдельного столбца с помощью оператора

alter table MYTABLE modify MYDATE not null;

.

Он будет отбрасываться с ORA-02296 cannot enable(<schema_name>.)-null values found, даже если для этого столбца найдена одна null запись.

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

1 голос
/ 27 февраля 2020

EXISTS вернется, как только найдет значение NULL:

select
  case 
    when exists (select 1 from MYTABLE where MYDATE is null) then 1 
    else 0
  end
from dual
0 голосов
/ 27 февраля 2020

Вы можете использовать словарь данных:

select num_nulls 
from user_tab_columns 
where table_name = 'MYTABLE' and column_name = 'MYDATE'

Имейте в виду, что значения в словаре обновляются только после анализа таблиц, поэтому возвращаемое значение может быть устаревшим. Анализ таблиц может быть принудительно вызван:

ANALYZE TABLE MYTABLE COMPUTE STATISTICS FOR TABLE;

или использованием DBMS_STATS.GATHER_SCHEMA_STATS

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...