【发布时间】:2016-12-27 13:20:42
【问题描述】:
我正在从事一个拥有大型 Question 银行的项目,对于系统的 Tests added,根据以下查询在运行时动态获取 20 个问题:
SELECT Question.* from Question JOIN Test
ON Question.Subject_ID = Test.Subject_ID
AND Question.Question_Level = Test.Test_Level
ORDER BY RAND()
LIMIT 20;
不过,众所周知,RAND() 函数 MySQL 会杀死你的服务器,我一直在寻找更好的解决方案。
结果 EXPLAIN [above query]:
+----+-------------+----------+------+---------------+------+---------+------+------+----------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+----------+------+---------------+------+---------+------+------+----------------------------------------------------+
| 1 | SIMPLE | Test | ALL | NULL | NULL | NULL | NULL | 5 | Using temporary; Using filesort |
| 1 | SIMPLE | Question | ALL | NULL | NULL | NULL | NULL | 7 | Using where; Using join buffer (Block Nested Loop) |
+----+-------------+----------+------+---------------+------+---------+------+------+----------------------------------------------------+
结果 EXPLAIN Question:
+-------------------+------------------------------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------------+------------------------------------------+------+-----+---------+----------------+
| Question_ID | int(11) | NO | PRI | NULL | auto_increment |
| Questions | varchar(100) | NO | | NULL | |
| Available_Options | varchar(200) | NO | | NULL | |
| Correct_Answer | varchar(50) | NO | | NULL | |
| Subject_ID | int(11) | NO | | NULL | |
| Question_Level | enum('Beginner','Intermediate','Expert') | NO | | NULL | |
| Created_By | int(11) | NO | | NULL | |
+-------------------+------------------------------------------+------+-----+---------+----------------+
结果 EXPLAIN Test:
+----------------+------------------------------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------+------------------------------------------+------+-----+---------+----------------+
| Test_ID | int(11) | NO | PRI | NULL | auto_increment |
| Test_Name | varchar(50) | NO | | NULL | |
| Test_Level | enum('Beginner','Intermediate','Expert') | NO | | NULL | |
| Subject_ID | int(11) | NO | | NULL | |
| Question_Count | int(11) | NO | | NULL | |
| Created_By | int(11) | NO | | NULL | |
+----------------+------------------------------------------+------+-----+---------+----------------+
如果能帮助优化查询以减少服务器负载和执行时间,我们将不胜感激。
附注系统也有删除能力,所以QUESTION和TEST表的AUTO_INCREMENT PRIMARY KEY可以有很大的差距。
【问题讨论】:
-
显示
EXPLAIN的结果 -
添加了
EXPLAIN结果 -
您有关于 Question.Subject_ID、Test.Subject_ID、Question.Question_Level、Test.Test_Level 的索引吗?
-
不,我正在加入非关键列,因为这是系统要求的。
-
您必须为这些列添加索引以进行快速连接