Can select * usage ever be justified?

SqlSelect

Sql Problem Overview


I've always preached to my developers that SELECT * is evil and should be avoided like the plague.

Are there any cases where it can be justified?

I'm not talking about COUNT(*) - which most optimizers can figure out.

Edit

I'm talking about production code.

And one great example I saw of this bad practice was a legacy asp application that used select * in a stored procedure, and used ADO to loop through the returned records, but got the columns by index. You can imagine what happened when a new field was added somewhere other than the end of the field list.

Sql Solutions


Solution 1 - Sql

I'm quite happy using * in audit triggers.

In that case it can actually prove a benefit because it will ensure that if additional columns are added to the base table it will raise an error so it cannot be forgotten to deal with this in the audit trigger and/or audit table structure.

(Like dotjoe) I am also happy using it in derived tables and column table expressions. Though I habitually do it the other way round.

WITH t
     AS (SELECT *,
                ROW_NUMBER() OVER (ORDER BY a) AS RN
         FROM   foo)
SELECT a,
       b,
       c,
       RN
FROM   t; 

I'm mostly familiar with SQL Server and there at least the optimiser has no problem recognising that only columns a,b,c will be required and the use of * in the inner table expression does not cause any unnecessary overhead retrieving and discarding unneeded columns.

In principle SELECT * ought to be fine in a view as well as it is the final SELECT from the view where it ought to be avoided however in SQL Server this can cause problems as it stores column metadata for views which is not automatically updated when the underlying tables change and the use of * can lead to confusing and incorrect results unless sp_refreshview is run to update this metadata.

Solution 2 - Sql

There are many scenarios where SELECT * is the optimal solution. Running ad-hoc queries in Management Studio just to get a sense of the data you're working with. Querying tables where you don't know the column names yet because it's the first time you've worked with a new schema. Building disposable quick'n'dirty tools to do a one-time migration or data export.

I'd agree that in "proper" development, you should avoid it - but there's lots of scenarios where "proper" development isn't necessarily the optimum solution to a business problem. Rules and best practices are great, as long as you know when to break them. :)

Solution 3 - Sql

I'll use it in production when working with CTEs. But, in this case it's not really select *, because I already specified the columns in the CTE. I just don't want to respecify in the final select.

with t as (
    select a, b, c from foo
)

select t.* from t;

Solution 4 - Sql

None that I can think of, if you are talking about live code.

People saying that it makes adding columns easier to develop (so they automatically get returned and can be used without changing the Stored procedure) have no idea about writing optimal code/sql.

I only ever use it when writing ad-hoc queries that will not get reused (finding out the structure of a table, getting some data when I am not sure what the column names are).

Solution 5 - Sql

I think using select * in an exists clause is appropriate:

select some_field from some_table 
where exists 
 (select * from related_table [join condition...])

Some people like to use select 1 in this case, but it's not elegant, and it doesn't buy any performance improvements (early optimization strikes again).

Solution 6 - Sql

In production code, I'd tend to agree 100% with you.

However, I think that the * more than justifies its existence when performing ad-hoc queries.

Solution 7 - Sql

You've gotten a number of answers to your question, but you seem to be dismissing everything that isn't parroting back what you want to hear. Still, here it is for the third (so far) time: sometimes there is no bottleneck. Sometimes performance is way better than fine. Sometimes the tables are in flux, and amending every SELECT query is just one more bit of possible inconsistency to manage. Sometimes you've got to deliver on an impossible schedule and this is the last thing you need to think about.

If you live in bullet time, sure, type in all the column names. But why stop there? Re-write your app in a schema-less dbms. Hell, write your own dbms in assembly. That'd really show 'em.

Solution 8 - Sql

And remember if you use select * and you have a join at least one field will be sent twice (the join field). This wastes database resources and network resources for no reason.

Solution 9 - Sql

As a tool I use it to quickly refresh my memory as to what I can possibly get back from a query. As a production level query itself .. no way.

Solution 10 - Sql

When creating an application that deals with the database, like phpmyadmin, and you are in a page where to display a full table, in that case using SELECT * can be justified, I guess.

Solution 11 - Sql

About the only thing that I can think of would be when developing a utility or SQL tool application that is being written to run against any database. Even here though, I would tend to query the system tables to get the table structure and then build any necessary query from that.

There was one recent place where my team used SELECT * and I think that it was ok... we have a database that exists as a facade against another database (call it DB_Data), so it is primarily made up of views against the tables in the other database. When we generate the views we actually generate the column lists, but there is one set of views in the DB_Data database that are automatically generated as rows are added to a generic look-up table (this design was in place before I got here). We wrote a DDL trigger so that when a view is created in DB_Data by this process then another view is automatically created in the facade. Since the view is always generated to exactly match the view in DB_Data and is always refreshed and kept in sync, we just used SELECT * for simplicity.

I wouldn't be surprised if most developers went their entire career without having a legitimate use for SELECT * in production code though.

Solution 12 - Sql

I've used select * to query tables optimized for reading (denormalized, flat data). Very advantageous since the purpose of the tables were simply to support various views in the application.

Solution 13 - Sql

How else do the developers of phpmyadmin ensure they are displaying all the fields of your DB tables?

Solution 14 - Sql

It is conceivable you'd want to design your DB and application so that you can add a column to a table without needing to rewrite your application. If your application at least checks column names it can safely use SELECT * and treat additional columns with some appropriate default action. Sure the app could consult system catalogs (or app-specific catalogs) for column information, but in some circumstances SELECT * is syntactic sugar for doing that.

There are obvious risks to this, however, and adding the required logic to the app to make it reliable could well simply mean replicating the DB's query checks in a less suitable medium. I am not going to speculate on how the costs and benefits trade off in real life.

In practice, I stick to SELECT * for 3 cases (some mentioned in other answers:

  • As an ad-hoc query, entered in a SQL GUI or command line.
  • As the contents of an EXISTS predicate.
  • In an application that dealt with generic tables without needing to know what they mean (e.g. a dumper, or differ).

Solution 15 - Sql

Yes, but only in situations where the intention is to actually get all the columns from a table not because you want all the columns that a table currently has.

For example, in one system that I worked on we had UDFs (User Defined Fields) where the user could pick the fields they wanted on the report, the order as well as filtering. When building a result set it made more sense to simply "select *" from the temporary tables that I was building instead of having to keep track of which columns were active.

Solution 16 - Sql

  1. I have several times needed to display data from a table whose column names were unknown. So I did SELECT * and got the column names at run time.

  2. I was handed a legacy app where a table had 200 columns and a view had 300. The risk exposure from SELECT * would have been no worse than from listing all 300 columns explicitly.

Solution 17 - Sql

Select * in production code is justifiable any time that:

  • it isn't a performance bottleneck
  • development time is critical

Why would I want the overhead of going back and having to worry about changing the relevant stored procedures, every time I add a field to the table?

Why would I even want to have to think about whether or not I've selected the right fields, when the vast majority of the time I want most of them anyway, and the vast majority of the few times I don't, something else is the bottleneck?

If I have a specific performance issue then I'll go back and fix that. Otherwise in my environment, it's just premature (and expensive) optimisation that I can do without.


Edit.. following the discussion, I guess I'd add to this:

... and where people haven't done other undesirable things like tried to access columns(i), which could break in other situations anyway :)

Solution 18 - Sql

If you want to find all the columns and want order, you can do the following (at least if you use MySQL):

SHOW COLUMNS FROM mytable FROM mydb; (1)

You can see every relevant information about all your fields. You can prevent problems with types and you can know for sure all the column names. This command is very quick, because you just ask for the structure of the table. From the results you will select all the name and will build a string like this:

"select " + fieldNames[0] + ", fieldNames[1]" + ", fieldNames[2] from mytable". (2)

If you don't want to run two separate MySQL commands because a MySQL command is expensive, you can include (1) and (2) into a stored procedure which will have the results as an OUT parameter, that way you will just call a stored procedure and every command and data generation will happen at the database server.

Solution 19 - Sql

Depends on the context of the production software.

If you are writing a simple data access layer for a table management tool where the user will be selecting tables and viewing results in a grid, then it would seem *SELECT ** is fine.

In other words, if you choose to handle "selection of fields" through some other means (as in automatic or user-specified filters after retrieving the resultset) then it seems just fine.

If on the other hand we are talking about some sort of enterprise software with business rules, a defined schema, etc. ... then I agree that *SELECT ** is a bad idea.

EDIT: Oh and when the source table is a stored procedure for a trigger or view, "*SELECT **" should be fine because you're managing the resultset through other means (the view's definition or the stored proc's resultset).

Solution 20 - Sql

I know I'm very late to the party but I'll chip in that I use select * whenever I know that I'll always want all columns regardless of the column names. This may be a rather fringe case but in data warehousing, I might want to stage an entire table from a 3rd party app. My standard process for this is to drop the staging table and run

select * 
into staging.aTable 
from remotedb.dbo.aTable

Yes, if the schema on the remote table changes, downstream dependencies may throw errors but that's going to happen regardless.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionScottEView Question on Stackoverflow
Solution 1 - SqlMartin SmithView Answer on Stackoverflow
Solution 2 - SqlDylan BeattieView Answer on Stackoverflow
Solution 3 - SqldotjoeView Answer on Stackoverflow
Solution 4 - SqlOdedView Answer on Stackoverflow
Solution 5 - SqlJordãoView Answer on Stackoverflow
Solution 6 - SqlAlex HumphreyView Answer on Stackoverflow
Solution 7 - SqlshanusmagnusView Answer on Stackoverflow
Solution 8 - SqlHLGEMView Answer on Stackoverflow
Solution 9 - SqlPeter MView Answer on Stackoverflow
Solution 10 - SqlaularonView Answer on Stackoverflow
Solution 11 - SqlTom HView Answer on Stackoverflow
Solution 12 - SqlAndrew ChurchView Answer on Stackoverflow
Solution 13 - SqlJD IsaacksView Answer on Stackoverflow
Solution 14 - SqlEdmundView Answer on Stackoverflow
Solution 15 - SqlBiff MaGriffView Answer on Stackoverflow
Solution 16 - SqlegruninView Answer on Stackoverflow
Solution 17 - SqlChrisAView Answer on Stackoverflow
Solution 18 - SqlLajos ArpadView Answer on Stackoverflow
Solution 19 - SqlAllbiteView Answer on Stackoverflow
Solution 20 - SqlBob ProbstView Answer on Stackoverflow