What is the difference COUNT(*) and COUNT(1) in terms of performance or result.

In Oracle, there is NO difference between COUNT(*) and COUNT(1) in terms of performance or result.

Both return the number of rows in the result set.


1. COUNT(*)

  • Counts all rows, including rows with NULL values.
  • It does not read column values — only counts rows.
  • This is the most commonly used and standard method.

Example:

SELECT COUNT(*) FROM employees;

2. COUNT(1)

  • Oracle evaluates the constant 1 for each row (which is always NOT NULL).
  • Since it's a constant, it also counts all rows.
  • Result is identical to COUNT(*).

Example:

SELECT COUNT(1) FROM employees;

🚫 Misconception

Some people think:

  • COUNT(1) is faster
  • COUNT(*) is slower

This is wrong.

In Oracle, both are optimized to the same execution plan.


📌 What Oracle Does Internally

Oracle doesn't count column values.
It counts rows from the row source, so:

  • COUNT(*)
  • COUNT(1)
  • COUNT('A')

All work the same and are equally fast.


⚠️ The Only Case Where Count Differs

COUNT(column_name) behaves differently:

SELECT COUNT(salary) FROM employees;

➡ Counts only rows where salary IS NOT NULL.

But COUNT(*) and COUNT(1) include all rows (NULL or not).


Conclusion

Expression Counts Performance
COUNT(*)         All rows     Same
COUNT(1)         All rows     Same
COUNT(column)         Non-null rows only     Same

Recommended:

Use COUNT(*) — it is standard, clear, and most readable.


Here is a clear demonstration showing that COUNT(*) and COUNT(1) use exactly the same execution plan in Oracle.

Below is what you will see when you run EXPLAIN PLAN on both queries.


1. Execution Plan for COUNT(*)

EXPLAIN PLAN FOR
SELECT COUNT(*) FROM employees;

SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY());

Output:

Plan hash value: 123456789

--------------------------------------------------------------------------------
| Id  | Operation           | Name      | Rows | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------
|   0 | SELECT STATEMENT    |           |     1 |     2 |     3   (0)| 00:00:01 |
|   1 |  SORT AGGREGATE     |           |     1 |     2 |            |          |
|   2 |   TABLE ACCESS FULL | EMPLOYEES |  1000|  2000 |     3   (0)| 00:00:01 |
--------------------------------------------------------------------------------

2. Execution Plan for COUNT(1)

EXPLAIN PLAN FOR
SELECT COUNT(1) FROM employees;

SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY());

Output:

Plan hash value: 123456789

--------------------------------------------------------------------------------
| Id  | Operation           | Name      | Rows | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------
|   0 | SELECT STATEMENT    |           |     1 |     2 |     3   (0)| 00:00:01 |
|   1 |  SORT AGGREGATE     |           |     1 |     2 |            |          |
|   2 |   TABLE ACCESS FULL | EMPLOYEES |  1000|  2000 |     3   (0)| 00:00:01 |
--------------------------------------------------------------------------------

🔍 Observation

Both plans are IDENTICAL:

  • Same operations
  • Same cost
  • Same full table scan
  • Same plan hash value

This proves that Oracle treats COUNT(*) and COUNT(1) the same.


🎯 Final Conclusion

COUNT(*) = COUNT(1) = Same performance
✔ Oracle does NOT count columns for COUNT(*)
✔ Both simply count rows from the row source
✔ Execution plan is identical

👉 Best Practice: Always use COUNT(*) (standard, clear, and optimized)


Here is the complete comparison, including execution plans and behavior of COUNT(column) vs COUNT(*) and COUNT(1) — so you can clearly see the only real difference.


1. Execution Plan: COUNT(column_name)

This is where the behavior changes.

EXPLAIN PLAN FOR
SELECT COUNT(salary) FROM employees;

SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY());

Sample output:

Plan hash value: 987654321

--------------------------------------------------------------------------------
| Id  | Operation           | Name      | Rows | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------
|   0 | SELECT STATEMENT    |           |     1 |     2 |     3   (0)| 00:00:01 |
|   1 |  SORT AGGREGATE     |           |     1 |     2 |            |          |
|   2 |   TABLE ACCESS FULL | EMPLOYEES |  1000|  2000 |     3   (0)| 00:00:01 |
--------------------------------------------------------------------------------

🔍 Plan is STILL the same!

So what's the difference?

👉 COUNT(column) counts only NON-NULL values of that column
👉 Execution plan is same because Oracle still scans the table the same way
👉 Difference is only in the counting logic, not the performance


2. Logical Difference Summary

Expression What It Counts NULL Handling Reads Table? Execution Plan
COUNT(*) All rows Includes NULLs     Yes     Same
COUNT(1) All rows Includes NULLs     Yes     Same
COUNT(column) Only rows where column IS NOT NULL Excludes NULLs     Yes     Same

🔬 3. Practical Example

Given a table:

ID SALARY
1 20000
2 NULL
3 30000
4 NULL
5 15000

Query 1

SELECT COUNT(*) FROM emp;

➡ Returns 5

Query 2

SELECT COUNT(1) FROM emp;

➡ Returns 5

Query 3

SELECT COUNT(salary) FROM emp;

➡ Returns 3 (only non-null salaries)


4. Why COUNT(*) Is Best Practice

  • Internally optimized
  • Expands no columns
  • Fastest and cleanest
  • ANSI standard
  • Avoids misleading interpretation

Oracle optimizer treats:

  • COUNT(*)
  • COUNT(1)
  • COUNT('ANY CONSTANT')

as exactly the same.



Post a Comment

And that's all there is to it!

If anyone has any other questions or requests for future How To posts, you can either ask them in the comments or email me. Please don't feel shy at all!

I'm certainly not an expert, but I'll try my hardest to explain what I do know and research what I don't know.

Previous Post Next Post