0

Basically what's the difference in terms of security and speed in these 2 queries?

SELECT * FROM `myTable`

and

SELECT `id`, `name`, `location`, `place` etc... FROM `myTable`

Would using * increase the benchmark on my query and perform slower than static rows?

Curtis
  • 2,646
  • 6
  • 29
  • 53
  • Basically, this is covered in every basic SQL tutorial, just like using a WHERE clause to return the number of rows you return. – Ken White Nov 30 '13 at 01:15
  • @KenWhite any need for the smart response? I simply wanted to get the same answer from numerous sources instead of 1? what's wrong with that? – Curtis Nov 30 '13 at 01:16
  • 1
    You shouldn't even use mysql anymore. mysql is officially deprecated as of php 5.5. Use mysqli and prepared statements. –  Nov 30 '13 at 01:16
  • @user2176127 theirs no reason to not use mySQL, it's just not recommended due to the increased security and framework that PDO, mySQLi etc.. bring – Curtis Nov 30 '13 at 01:17
  • 1
    @Curtis It's officially deprecated as of php 5.5. You shouldn't use deprecated stuff in new code. –  Nov 30 '13 at 01:17
  • It wasn't a smart response. This is something that should be covered quite well in any decent SQL tutorial, and it's a very vague question. "Basically what's the difference" is a very open-ended question that is asking for some opinion-based answers. So is the question about performance; you can't benchmark performance except by using your own data and SQL, comparing the difference between the two. "What's faster/slower" is only relevant when you have actual things to compare. "What's heavier, an orange or a tomato?" is very dependent on the two actual pieces of fruit being compared. – Ken White Nov 30 '13 at 01:21
  • @Curtis "It will be removed in a few versions" is a pretty good reason not to use the `mysql_*` functions now. – ceejayoz Nov 30 '13 at 02:20
  • @user2176127 Where does the question say anything about PHP? – Christopher Creutzig Nov 30 '13 at 09:12
  • @ChristopherCreutzig I just took a wild guess but his answer indicates that he uses PHP's ext/mysql. –  Nov 30 '13 at 11:36

3 Answers3

4

There won't be much appreciable difference in performance if you also select all columns individually.

The idea is to select only the data you require and no more, which can improve performance if there is alot of unneeded columns in your query, for example, when you join several tables.

Ofc, on the other side of the coin, using * makes life easier when you make changes to the table.

Ashigore
  • 4,618
  • 1
  • 19
  • 39
0

Security-wise, the less you select, the less potentially sensitive data can be inadvertently dumped to the user's browser. Imagine if * included the column social_security_number and somewhere in your debug code it gets printed out as an HTML comment.

Performance-wise, in many cases your database is on another server, so requesting the entire row when you only need a small part of it means a lot more data going over the network.

ceejayoz
  • 176,543
  • 40
  • 303
  • 368
0

There is not a single, simple answer, and your literal question cannot fully be answered without more detail of the specific table structure, but I'm going with the assumption that you aren't actually talking about a specific query against a specific table, but rather about selecting columns explicitly or using the *.

SELECT * is always wasteful of something unless you are actually going to use every column that exists in the rows you're reading... maybe network bandwidth, or CPU resources, or disk I/O, or a combination, but something is being unnecessarily used, though that "something" may be in very small and imperceptible quantities ... or it may not ... but it can add up over time.

The two big examples that come to mind where SELECT * can be a performance killer are cases like...

...tables with long VARCHAR and BLOB columns:

Columns such as BLOB and VARCHAR that are too long to fit on a B-tree page are stored on separately allocated disk pages called overflow pages. We call such columns off-page columns. The values of these columns are stored in singly-linked lists of overflow pages, and each such column has its own list of one or more overflow pages

http://dev.mysql.com/doc/refman/5.6/en/innodb-row-format-overview.html

So if * includes columns that weren't stored on-page with the rest of the row data, you just took an I/O hit and/or wasted space in your buffer pool with accesses that could have been avoided had you selected only what you needed.

...also cases where SELECT * prevents the query from using a covering index:

If the index is a covering index for the queries and can be used to satisfy all data required from the table, only the index tree is scanned. In this case, the Extra column says Using index. An index-only scan usually is faster than ALL because the size of the index usually is smaller than the table data.

http://dev.mysql.com/doc/refman/5.6/en/explain-output.html

When one or more columns are indexed, copies of the column data are stored, sorted, in the index tree, which also includes the primary key, for finding the rest of the row data. When selecting from a table, if all of the columns you are selecting can be found within a single index, the optimizer will automatically choose to return the data to you by reading it directly from the index, instead of going to the time and effort to read in all of the row data... and this, some cases, is a very significant difference in the performance of a query, because it can mean substantially smaller resource usage.

If EXPLAIN SELECT does not reveal the exact same query plan when selecting the individual columns you need compared with the plan used when selecting *, then you are looking at some fairly hard evidence that you are putting the server through unnecessary work by selecting things you aren't going to use.

In additional cases, such as with the information_schema tables, the columns you select can make a particularly dramatic and obvious difference in performance. The information_schema tables are not actually tables -- they're server internal structures exposed via the SQL interface... and the columns you select can significantly change the performance of the query because the server has to do more work to calculate the values of some columns, compared to others. A similar situation is true of FEDERATED tables, which actually fetch data from a remote MySQL server to make a foreign table appear logically to be local. The columns you select are actually transferred across the network between servers.

Explicitly selecting the columns you need can also lead to fewer sneaky bugs. If a column you were using in code is later dropped from a table, the place in your code's data structure -- in some languages -- is going to contain an undefined value, which in many languages is the same think you would see if the column still existed but was null... so the code thinks "okay, that's null, so..." a logical error follows. Had you explicitly selected the columns you wanted, subsequent executions of the query would throw a hard error instead of quietly misbehaving.

MySQL's C-client API, which some other client libraries are built on, supports two modes of fetching data, one of which is mysql_store_result, which buffers the data from the server on the client side before the application actually reads it into its internal structures... so as you are "reading from the server" you may have already implicitly allocated a lot of memory on the client side to store that incoming result-set even when you think you're fetching a row at a time. Selecting unnecessary columns means even more memory needed.

SELECT COUNT(*) is an exception. The COUNT() function counts the number of non-null values seen, and * merely means "count the rows"... it doesn't examine column data, so if you want a star there, go for it.

As a favor to your future self, unless you want to go back later and rewrite all of those queries when you're trying to get more performance out of your server, you should bite the bullet and do the extra typing, now.

As a bonus, when other people see your code, they won't accuse you of laziness or inexperience.

Community
  • 1
  • 1
Michael - sqlbot
  • 169,571
  • 25
  • 353
  • 427