SELECT *

,

SELECT * feels convenient, but in SQL Server it bloats I/O, burns network bandwidth, blocks covering-index usage, and makes code brittle when schemas change. Specify only the columns you need—your DBAs (and your latency) will thank you.

Top 5 reasons

  1. Extra I/O and bigger result payloads

    Fetching every column—including wide MAX types—moves more data from disk and across the network than needed, hurting throughput. Microsoft notes the performance implications of wide tables/rows; real-world demos also show SELECT * inflating query costs. 

  2. Prevents covering indexes and triggers key lookups/scans

    The optimizer can only use a covering nonclustered index (often via INCLUDE) when it knows the exact columns. With SELECT *, SQL Server frequently adds Key Lookup operators or falls back to broader scans.

  3. Schema-fragile and brittle bindings

    Adding/removing/reordering columns can break client bindings and ORMs, or silently change result shapes. This is a well-documented anti-pattern in engineering discussions and postmortems. 

  4. Unnecessary data exposure (security & compliance)

    Returning columns you don’t need violates least-privilege principles and increases the chance of leaking sensitive fields (PII, secrets). 

  5. Poor readability and maintainability

    Explicit column lists self-document intent and make reviews/tuning easier; many SQL style guides flag SELECT * as a bad practice.

Better pattern (example)

-- Ask for only what you need SELECT o.OrderID, o.OrderDate, o.CustomerID FROM dbo.Orders AS o WHERE o.OrderDate >= @FromDate; -- Enable a covering read (no Key Lookups) CREATE INDEX IX_Orders_OrderDate ON dbo.Orders (OrderDate) INCLUDE (OrderID, CustomerID);

Original post (opens in new tab)

Rate

4 (1)

You rated this post out of 5. Change rating

Share

Share

Rate

4 (1)

You rated this post out of 5. Change rating