dedecms 运行在mysql 5.6.15 上 ordey limit 的奇怪问题
问题是生成文章总是发现有部分文章不会生成,跟踪发现,10%的文章会没有生成
原因出在数据库上,
Order by和Limit混合使用引起的问题
如果在order by语句中返回的结果集有很多行,那么非排序的列的返回结果是不确定的,即随机的,所以如果配合limit的话每次返回的结果集的顺序是不固定的,比如下面这个例子
mysql> SELECT * FROM ratings ORDER BY category;
+—-+———-+——–+
| id | category | rating |
+—-+———-+——–+
| 1 | 1 | 4.5 |
| 5 | 1 | 3.2 |
| 3 | 2 | 3.7 |
| 4 | 2 | 3.5 |
| 6 | 2 | 3.5 |
| 2 | 3 | 5.0 |
| 7 | 3 | 2.7 |
+—-+———-+——–+
使用了limit以后,可发现id列和rating列和之前的结果集顺序有出入:
mysql> SELECT * FROM ratings ORDER BY category LIMIT 5;
+—-+———-+——–+
| id | category | rating |
+—-+———-+——–+
| 1 | 1 | 4.5 |
| 5 | 1 | 3.2 |
| 4 | 2 | 3.5 |
| 3 | 2 | 3.7 |
| 6 | 2 | 3.5 |
+—-+———-+——–+
如果你有必要保证每次有相同的结果集,则需要order by你需要的那几列了:
mysql> SELECT * FROM ratings ORDER BY category, id;
+—-+———-+——–+
| id | category | rating |
+—-+———-+——–+
| 1 | 1 | 4.5 |
| 5 | 1 | 3.2 |
| 3 | 2 | 3.7 |
| 4 | 2 | 3.5 |
| 6 | 2 | 3.5 |
| 2 | 3 | 5.0 |
| 7 | 3 | 2.7 |
+—-+———-+——–+
mysql> SELECT * FROM ratings ORDER BY category, id LIMIT 5;
+—-+———-+——–+
| id | category | rating |
+—-+———-+——–+
| 1 | 1 | 4.5 |
| 5 | 1 | 3.2 |
| 3 | 2 | 3.7 |
| 4 | 2 | 3.5 |
| 6 | 2 | 3.5 |
+—-+———-+——–+
Order by和limit一起使用的优化原理
从MySQL5.6.2版本以后,优化器将更加智能地处理下面形式的查询了
SELECT … FROM single_table … ORDER BY non_index_column [DESC] LIMIT [M,]N;
这种在很大的结果集中只返回很少的行数的查询类型在web应用中非常常见,比如
SELECT col1, … FROM t1 … ORDER BY name LIMIT 10;
SELECT col1, … FROM t1 … ORDER BY RAND() LIMIT 15;
排序缓存有一个参数是sort_buffer_size,如果这个参数大小足够上面范例中的N行的排序结果集(如果M也被定义,那就是M+N行的结果集大小),那么服务器将会避免一个文件排序操作,使得排序完全在内存中完成。
最活跃的读者