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行的结果集大小),那么服务器将会避免一个文件排序操作,使得排序完全在内存中完成。

打赏

本文固定链接: https://www.cxy163.net/archives/1050 | 绝缘体

该日志由 绝缘体.. 于 2016年04月13日 发表在 MySQL, 首页 分类下,
原创文章转载请注明: dedecms 运行在mysql 5.6.15 上 ordey limit 的奇怪问题 | 绝缘体

报歉!评论已关闭.