17 | 如何正确地显示随机消息?
select word from words order by rand() limit 3;
这条语句会扫描2count(*)+3行,执行如下:这里用到了内存临时表
set tmp_table_size=1024; set sort_buffer_size=32768; set max_length_for_sort_data=16; /* 打开 optimizer_trace,只对本线程有效 */ SET optimizer_trace='enabled=on'; /* 执行语句 */ select word from words order by rand() limit 3; /* 查看 OPTIMIZER_TRACE 输出 */ SELECT * FROM `information_schema`.`OPTIMIZER_TRACE`\G
如果sort_buffer_size大于排序是数据,那么会用rowid排序(队列优先排序算法),如果小于,则采用并轨排序(需要使用临时文件)
可以这样子优化
mysql> select count(*) into @C from t;
set @Y1 = floor(@C * rand());
set @Y2 = floor(@C * rand());
set @Y3 = floor(@C * rand());
select * from t limit @Y1,1; //在应用代码里面取Y1、Y2、Y3值,拼出SQL后执行
select * from t limit @Y2,1;
select * from t limit @Y3,1;