一个简单的sql优化

Simple optimizations

You can sometimes use MyISAM’s COUNT(*) optimization to your advantage when you

want to count all but a very small number of rows that are well indexed. The following

example uses the standard world database to show how you can efficiently find the

number of cities whose ID is greater than 5. You might write this query as follows:

mysql> SELECT COUNT(*) FROM world.City WHERE ID > 5;

If you examine this query with SHOW STATUS, you’ll see that it scans 4,079 rows. If you

negate the conditions and subtract the number of cities whose IDs are less than or equal

to 5 from the total number of cities, you can reduce that to five rows:

242 | Chapter 6: Query Performance Optimization

mysql> SELECT (SELECT COUNT(*) FROM world.City) - COUNT(*)

-> FROM world.City WHERE ID <= 5;

This version reads fewer rows because the subquery is turned into a constant during

the query optimization phase, as you can see with EXPLAIN:

+----+-------------+-------+...+------+------------------------------+

| id | select_type | table |...| rows | Extra

|

+----+-------------+-------+...+------+------------------------------+

| 1 | PRIMARY

| City |...|

6 | Using where; Using index

|

| 2 | SUBQUERY

| NULL |...| NULL | Select tables optimized away |

+----+-------------+-------+...+------+------------------------------+

A frequent question on mailing lists and IRC channels is how to retrieve counts for

several different values in the same column with just one query, to reduce the number

of queries required. For example, say you want to create a single query that counts how

many items have each of several colors. You can’t use an OR (e.g., SELECT COUNT(color

= 'blue' OR color = 'red') FROM items;), because that won’t separate the different

counts for the different colors. And you can’t put the colors in the WHERE clause (e.g.,

SELECT COUNT(*) FROM items WHERE color = 'blue' AND color = 'red';), because the

colors are mutually exclusive. Here is a query that solves this problem:16

mysql> SELECT SUM(IF(color = 'blue', 1, 0)) AS blue,SUM(IF(color = 'red', 1, 0))

-> AS red FROM items;

And here is another that’s equivalent, but instead of using SUM() uses COUNT() and en-

sures that the expressions won’t have values when the criteria are false:

mysql> SELECT COUNT(color = 'blue' OR NULL) AS blue, COUNT(color = 'red' OR NULL)

-> AS red FROM items;

猜你喜欢

转载自abacus.iteye.com/blog/2050844