Яка різниця між кількістю вибору (*) та кількістю вибору (будь-яка_не_набірна_колонка)?


58

Здається, я пам’ятаю, що (в Oracle) є різниця між вимовою select count(*) from any_tableі select count(any_non_null_column) from any_table.

Які відмінності між цими двома твердженнями, якщо такі є?

Відповіді:


72
  • COUNT (*) буде включати NULLS
  • COUNT (column_or_expression) не буде.

Це означає, що ви COUNT(any_non_null_column)отримаєте те саме, що COUNT(*)і звичайно, оскільки немає значення NULL, які б викликали різниці.

Як правило, COUNT(*)має бути краще, тому що будь-який індекс може бути використаний, тому що COUNT(column_or_expression)він не може бути індексований або SARGable

З ANSI-92 (шукайте " Scalar expressions 125")

Справа:

а) Якщо вказано COUNT (*), то результат - кардинальність T.

b) В іншому випадку нехай TX - це стовпчаста таблиця, яка є результатом застосування <значення виразу> до кожного рядка T та усунення нульових значень. Якщо одне або кілька нульових значень усунене, тоді виконується умова завершення: попереджувальне - нульове значення усувається у встановленій функції.

Ті ж правила принаймні застосовуються і до SQL Server та Sybase

Примітка: COUNT (1) - це те саме, що і COUNT (*), оскільки 1 - це не нульовий вираз.


4
Просто для повноти: Oracle буде використовувати індексне сканування в індексованому ненульовому стовпчику, якщо count(*)використовується.
a_horse_with_no_name

Я подумав, що три можливі варіанти є COUNT(*), COUNT(<constant>)і COUNT(<column name>)що всі три можуть бути префіксованими ALLабо DISTINCT(за замовчуванням, ALLякщо вони відсутні). Мені просто цікаво, який вираз можна використовувати там, де ви говорите _or_expression?
день, коли

2
@onedaywhen COUNT(1)як марний приклад, це те саме, що COUNT(*). COUNT(CASE WHEN a>b THEN 1 END)як приклад, що рахує рядки, де a> b.
ypercubeᵀᴹ

16

У будь-якій останній (тобто 8.x + ) версії Oracle вони роблять те саме . Іншими словами, єдина різниця - семантична:

select count(*) from any_table

легко читається і очевидно, що ви намагаєтеся зробити, і

select count(any_non_null_column) from any_table

важче читати, тому що

  1. це довше
  2. він менш пізнаваний
  3. Ви повинні подумати про те, чи any_non_null_columnнасправді виконується якnot null

Словом, використовуйтеcount(*)



1

У книзі Керівництва з іспиту з сертифікації професійного сертифікату DBA (Oracle8i) (ISBN 0072130601) на сторінці 78 сказано, що COUNT (1) буде працювати швидше, ніж COUNT (*), тому що певні механізми запускаються в дію для перевірки словника даних на зведеність кожної колонки (або принаймні перший стовпець, що не зводить нанівець) при використанні COUNT (*) . COUNT (1) обходить ці механізми.

MySQL чити для 'SELECT COUNT (1) на tblname;' на таблицях MyISAM, читаючи заголовок таблиці для кількості таблиць. InnoDB рахується кожного разу.

Щоб перевірити, чи буде COUNT (1) працювати швидше, ніж COUNT (*), в аггностичному порядку, просто запустіть наступне та оцініть час роботи для себе:

SELECT COUNT(1) FROM tblname WHERE 1 = 1;
SELECT COUNT(*) FROM tblname WHERE 1 = 1;
SELECT COUNT(column-name) FROM tblname WHERE 1 = 1;

Це змушує функцію COUNT працювати на одному рівні рівних рівнів незалежно від двигуна зберігання даних або RDBMS.


8
Посібник з іспиту неправильний. В Oracle count (*) = count (1) (принаймні після версії 7). Дивіться asktom.oracle.com/pls/asktom/… (вже посилається на @JackPDouglas)
Лей Ріффер

3
Цікаво. COUNT (*) взагалі не повинен перевіряти стовпці відповідно до специфікації ANSI. Було поставлено на SO для SQL Server деякий час назад теж stackoverflow.com/questions/1221559/count-vs-count1 / ...
ГБН

@gbn, @Leigh Riffel, @bernd_k Дякую за те, що приєднався і нагадав мені читати та дізнаватися більше, тим більше, що я не працюю з Oracle деякий час.
RolandoMySQLDBA
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.