Почему Select 1 быстрее, чем Select count(*)?


В Oracle, при запросе существования строки, почему Select 1 быстрее, чем Select count (*)?

7 9

7 ответов:

Поскольку Oracle не поддерживает IF EXISTS в PL / SQL, предложение CodeByMidnight использовать EXISTS обычно делается с помощью чего-то вроде

SELECT 1 
  INTO l_local_variable 
  FROM dual 
 WHERE EXISTS( 
    SELECT 1 
      FROM some_table 
     WHERE some_column = some_condition ); 
Oracle знает, что он может прекратить обработку предложения WHERE EXISTS, как только будет найдена одна строка, поэтому ему не нужно потенциально подсчитывать большое количество строк, соответствующих критериям. Это меньше беспокоит, конечно, если вы проверяете, существует ли строка с определенным ключом, чем если вы проверяете условие, включающее неиндексированные столбцы или проверка условия, которое может привести к возвращению большого количества строк.

(примечание: Я хотел бы опубликовать это как комментарий к сообщению CodeByMidnight, но комментарии не могут включать форматированный код).

Обновление: учитывая разъяснение, сделанное оригинальным плакатом в их комментарии, короткий, окончательный ответ заключается в том, что a SELECT 1 или SELECT COUNT(1) не быстрее, чем a SELECT COUNT(*). Вопреки всем рекомендациям по кодированию, на которые вы смотрите, COUNT(*) является предпочтительным способом подсчета все строки. Существовал старый миф, что a COUNT(1) быстрее. Как минимум, это не было правдой ни в одной версии Oracle, выпущенной за последнее десятилетие, и маловероятно, что это когда-либо было правдой. Однако это было широко распространенное убеждение. Сегодня код, который делает COUNT(1), а не COUNT(*), как правило, заставляет меня подозревать, что автор склонен верить различным мифам Оракула, поэтому я бы предложил использовать COUNT(*).

Лучше все же использовать EXISTS там, где RDBMS поддерживает его или эквивалент, так как это остановит обработку строк, как только он найдет совпадение.

Я был бы удивлен, если бы select count(*) не был должным образом оптимизирован, нет необходимости загружать все столбцы, поскольку не будет обработки, связанной с столбцами.

Поскольку звезда принимает все cols в число, "1" является собственным типом данных.

В MySQL "SELECT COUNT(name_of_the_primary_key)" должен быть таким же быстрым, как ваш SELECT 1. Это индекс, который имеет значение. Счетчик() по индексу должен быть достаточно быстрым ;)

Я не думаю, что это верно для Oracle. http://justoracle.blogspot.com/2006/12/count-vs-count1.html

Но, в некоторых базах данных причина заключается в том, что ' * ' должен посетить таблицы метаданных. Это имеет тенденцию добавлять ненужные накладные расходы. Где а 1-это просто буквальное.

При прочих равных условиях "select 1 from my_table" вернет Первый результат быстрее, чем "select count(*) from my_table", но если вы получите все результаты из запроса, то count(*) будет быстрее, потому что он включает гораздо меньше данных (1 целое число, в отличие от 1 целого числа на каждую строку в таблице).