tags:

views:

1680

answers:

20

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.

+22  A: 

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).

Oded
+7  A: 

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.

Alex Humphrey
+25  A: 

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. :)

Dylan Beattie
"Querying tables where you don't know the column names yet because it's the first time you've worked with a new schema" - e.g. when implementing an ORM that builds its objects from the DB schema, rather than the other way around.
Steve Jessop
"Rules and best practices are great, as long as you know when to break them" +1, I'm always being told "that's good enough".
What
Unfortunately, in my experience, this is not why people use select * - they use it due to laziness.
ScottE
+1  A: 

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.

Peter M
+2  A: 

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.

aularon
Nope it can't in that case. Select * is still a performance problem and columns are added to tables for adminstrative purposes that users should not see like GUIDs.
HLGEM
I understand, but in application in the nature of phpmyadmin, where the user is a database administrator, who build and is allowed to see column names, in that case I think it's justified to just use `SELECT *`, and I don't think it will be slower than building a query with _all_ fieldnames and execute it.
aularon
+1, aularon. I was using a DB editor the other day that has this problem. Whenever a column changed outside the editor I had to manually refresh the metadata to get the table views to show the new columns. If the editor just did a `SELECT *` when it queried, I wouldn't have to worry about cached metadata being out-of-date.
Gabe
+28  A: 

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.

Martin Smith
+1, and when not using a trigger but an OUTPUT clause to send the data to a audit table as well
KM
This is a good example.
ScottE
+12  A: 

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).

Jordão
`select 1` is early optimization and not elegant? wha?! lol, it's the difference between 1 character or another. Hardly takes any effort. Actually, `select 1` probably shows a better understanding of the exists clause. It only cares about rows.
dotjoe
@dotjoe: The problem with `select 1` is that people think they're creating a smart optimization (I heard it numerous times). They're not. As for the conceptual difference, an exists clause serves to check if _any_ row exists, not just 1, so I think * is better to describe _any_ than 1.
Jordão
Yea, I said the exists clause only cares about rows. So, why do we need to use *, which only relates to columns? By using 1 you clearly show that we don't care about the columns, only rows.
dotjoe
My problem with the 1 is the "I'm a smart optimizer" problem. Some people even go as far as using `select top 1 1` (in SQL-Server). As for the conceptual problems, I don't think we can ever reach an agreement. What we should be able to do in an exists clause, to really put an end to the debate, was to omit the columns altogether: `select from table`, or have another syntax that says "I don't care": `select _ from table` (borrowed from some functional languages). When the language doesn't provide the tools to express _exactly_ what we want, conceptual differences are all open to interpretation.
Jordão
this is kind of like count(*), but good point, +1
ScottE
I totally agree with that! where is the `exists(from table)` syntax? omit the select clause altogether would be my vote.
dotjoe
dotjoe: What are you talking about, you can't emit the `SELECT` clause.. Where did you get that syntax?
Evan Carroll
@Evan Carroll it's my pipe dream syntax request. it doesn't exist yet.
dotjoe
Definitive answer: it *is* acceptable. Anything else is ignorance/superstition. The ANSI standard mentions that the column list in the EXIST is not parsed. Page 191, http://www.contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt. Which leads to this snippet: ...EXISTS(SELECT 1/0 FROM... please see examples here: http://stackoverflow.com/questions/2019958/
gbn
@dotjoe, @Jordão: please see my comment above, I can't edit it now. And also see this: http://stackoverflow.com/questions/1597442
gbn
@ScottE: For COUNT(*), please see this http://stackoverflow.com/questions/1221559/count-vs-count1/1221649#1221649
gbn
@gbn: Thanks for the info. That's exactly what I hinted at when I mentioned that there're no performance differences between * and 1. It makes sense that the column list is completely ignored, as the only thing that matters is if rows exists. What's left, then, is a matter of style, and IMO * is better than the alternatives.
Jordão
oh I like that `select 1/0` example. See, they really should just drop the select part altogether. @Jordão I know you like your * but your only knock against my 1 is that some other dev thinks it's an optimization. And I say that's his problem not mine. lol.
dotjoe
OK, let's see if we can agree on this: `select 'rows' from table`. It still doesn't change the validity of my answer.
Jordão
+2  A: 

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.

Tom H.
+4  A: 

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.

HLGEM
+17  A: 

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;
dotjoe
Great example of a DRY approach. Don't repeat yourself.
Atømix
+1  A: 

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).
Edmund
+1  A: 

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.

Biff MaGriff
A: 

In summary we all agree with him, right? Because he is asking for a justified use in production code.

nwolisa
+1  A: 
  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.

egrunin
If you don't know the columns at run time, I would suspect a design problem. But true it is the only viable choice inthat case.
HLGEM
A: 

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 :)

ChrisA
Because you should see what is being returned and whether you need it in the stored proc now or not. Fields are often added that are not needed and which will confuse the user if they are shown. Being too lazy to do necessary maintenance when you make a change is an excuse not a good practice.
HLGEM
@ChrisA I agree with you. In some parts of an app performance is not particularly important, in which case Select * does fine thanks very much- listing the fields has an impact on future development time and potential future bugs
DannykPowell
Using select * is a maintenance nightmare. Been there, done that. Had to fix other's crappy code. Change your schema? Everything can break. Just don't use select * in production code.
Starkey
Confuse the user? What nonsense this is. As if 'select *' in the SQL implies anything at all about what will be shown to the user. Ever heard of separation of data layer from UI? It would seem not. And 'select *' can only break other things if they make assumptions about what columns appear in a particular order. Of course 'columns(i)' could break if the underlying data changes - but it could break if you specify the columns in your select too, and that changes. Still, stick to the usual religious dogma if you prefer.
ChrisA
A: 

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.

Lajos Arpad
+2  A: 

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.

Andrew Church
+5  A: 

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.

shanusmagnus
You're rocking the boat, SM. They all prefer to adhere to the religion in vogue, than notice that actually, one size doesn't fit all. I'm just surprised that no one's advocating automated tools (and their inevitable costs) to rewrite all that SQL that often doesn't need changing anyway.
ChrisA
A: 

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).

Allbite
A: 

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

John Isaacks