MySQL中,使用RAND()查询数据量比较大的优化
时间:2014-4-1 作者:smarteng 分类: 数据库相关
随机找出2万条纪录,
方案一:
最直接的语句是:
SELECT *
FROM moni_role
ORDER BY RAND()
LIMIT 20000;
mysql> EXPLAIN SELECT FROM moni_role ORDER BY RAND() LIMIT 20000;
+----+-------------+-----------+------+---------------+------+---------+------+---------+---------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-----------+------+---------------+------+---------+------+---------+---------------------------------+
| 1 | SIMPLE | moni_role | ALL | NULL | NULL | NULL | NULL | 1344687 | Using temporary; Using filesort |
+----+-------------+-----------+------+---------------+------+---------+------+---------+---------------------------------+
mysql> SELECT FROM moni_role ORDER BY RAND() LIMIT 20000;
...此处省去结果
20000 rows in set (57.16 sec)
这条语句花了将近一分钟,尝试优化后的语句。
方案二:
借助子查询,在子查询里覆盖索引
SELECT
FROM moni_role
WHERE id IN (
SELECT id FROM moni_role
ORDER BY RAND()
)
LIMIT 20000;
mysql> EXPLAIN SELECT FROM moni_role WHERE id IN ( SELECT id FROM moni_role ORDER BY RAND() ) LIMIT 20000;
+----+--------------------+-----------+-----------------+---------------+---------+---------+------+---------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+--------------------+-----------+-----------------+---------------+---------+---------+------+---------+-------------+
| 1 | PRIMARY | moni_role | ALL | NULL | NULL | NULL | NULL | 1344687 | Using where |
| 2 | DEPENDENT SUBQUERY | moni_role | unique_subquery | PRIMARY | PRIMARY | 4 | func | 1 | Using index |
+----+--------------------+-----------+-----------------+---------------+---------+---------+------+---------+-------------+
mysql> SELECT * FROM moni_role WHERE id IN ( SELECT id FROM moni_role ORDER BY RAND() ) LIMIT 20000;
...此处省去结果
20000 rows in set (0.33 sec)
可以看到优化后的语句只花了330毫秒,性能提高了200倍左右。