【发布时间】:2014-05-29 12:25:02
【问题描述】:
我有一个非常直接的查询导致我的 MySQL 服务器崩溃。当我运行它时,它会失去与 MySQL 的连接,服务器需要一段时间才能恢复。
由于某种原因,我在中断期间运行 SHOW FULL processlist 时得到了这个:
5 debian-sys-maint localhost Query 0 Opening tables select count(*) into @discard from `information_schema`.`COLUMNS`
我相信那是 MySQL 做的事,不是我的连接。
我正在运行的查询如下:
SELECT
f.title,
q.title,
AVG(answer) AS average_answer,
COUNT(DISTINCT a.id) AS number_of_answers
FROM
answers a
INNER JOIN forms f
ON f.id = a.form_id
INNER JOIN questions q
ON a.question_id = q.id
WHERE
a.form_id IN (1,2,3)
GROUP BY
f.title,
q.title;
(请注意我更改了别名和表名,因此请忽略任何拼写错误。)
问题是,如果我在没有 2 个函数(AVG 和 COUNT)之一的情况下运行查询,这将有效。如果我一起运行它们,我的连接就会消失。
我运行它的数据集将是 ~12.000.000 条记录,但 WHERE f.id IN(1,2,3) 将集合限制为 30 或 40。如果我运行 SELECT * FROM answers WHERE form_id IN (1,2,3),WHERE 子句很快,我得到的结果为 0 ,01 秒。
为什么这种功能组合会让服务器头晕目眩?
编辑: 这是 EXPLAIN 的输出。不过,要正确格式化它有点困难:
1 SIMPLE f range PRIMARY PRIMARY 4 3 Using where; Using index; Using temporary; Using filesort
1 SIMPLE a ref form_fk,question_fk,fk_answer_quality form_fk 5 f.id 16 Using where
1 SIMPLE q eq_ref PRIMARY PRIMARY 4 a.question_id 1
问题似乎在第一行,但我没有得到“范围”部分。
【问题讨论】:
-
你在 a.form_id 上有索引吗?
-
这是一个外键,所以是的。正如我在问题中添加的那样:
SELECT * FROM answers WHERE form_id IN (1,2,3)在几分之一秒内完成。 -
您是否尝试过使用 EXPLAIN SELECT 来查看数据库将如何优化它?
-
为确保您的查询没有问题,您可以在 sqlfiddle.com 上复制 3 个表的架构。无需插入所有行。只需大约 100 行就足够了。你可以导出你的sql并通过复制粘贴sql来导入它。
-
我正在尝试查看更改列的数据类型是否有任何不同。答案列的类型为 TEXT。我确实在 WHERE 子句中排除了所有非数字答案,但这就是我现在正在研究的内容。