【发布时间】:2015-10-22 01:22:20
【问题描述】:
我有一个不到 2 亿行的 MySQL 表。我有一个看起来像这样的 Django 查询:
foo.objects.filter(field1_id__in=[about 27 items],
field2_id__in=[about 25 values],
field3=value)
我注意到运行此过滤器的页面今天挂起。昨天的页面在大约一秒钟内呈现。随着更多数据的添加,field1 列表会随着时间的推移而增长,而 field2 列表的大小是恒定的。以交互方式处理这些查询,我确定有一个悬崖,如果我只指定 field2“in”的前 9 个值,查询会在大约一秒钟内返回,但如果我移动到 field2 列表中的 10 个值,则查询“永远”挂起。
如此严重的退化有意义吗?没有连接也没有依赖查询,只有一个 WHERE 与 3 个子句 AND 在一起,其中两个是 IN。感觉像一个 MySQL 错误...?或者“这就是 MySQL 的生活?”
编辑:刚刚返回的 10 项 field2_id__in 查询:花了大约 45 分钟!
原始查询
SELECT `mytable`.`id`, `mytable`.`field1_id`, `mytable`.`field2_id`, `mytable`.`field3_id`, `mytable`.`field4_id`, `mytable`.`data` FROM `mytable` WHERE (`mytable`.`field2_id` IN (44942, 42953, 43099, 43330, 45165, 45468, 43518, 45620, 43693, 45760, 43790, 45930, 43885, 46026, 46120, 44158, 46298, 44314, 42204, 46492, 44441, 42327, 44586, 42515, 44726, 44835, 42802) AND `mytable`.`field3_id` IN (3, 17, 696, 150, 170, 51, 6528, 2383, 3342, 2289, 6491, 6375,2070, 6186, 318, 6498, 5197, 6011, 5833, 7803, 5195, 4871, 6928, 6531) AND `mytable`.`field4_id` = 11 )
解释输出
select_type: simple
type: range
possible_keys: (3 keys)
key: (key)
key_len: 4
ref: NULL
rows: 14160
extra: Using index condition; Using where
【问题讨论】:
-
两个 cmets:首先,您是否尝试过直接从 MySQL 运行各种版本的查询?二、你有没有试过用
EXPLAIN看看执行计划是什么? -
field_2的data_type是什么?
-
我都没做过。解释听起来是个好主意。 field1 和 field2 都是外键,但查询在 id 上,所以它是简单的整数比较。
-
是的,当直接在 MySQL 中执行时,查询会挂起。我运行了解释,但不知道如何解释结果。 select_type: simple, type: range, possible_keys: (3 keys), key: (key), key_len: 4, ref: NULL, rows: 14160 extra: 使用索引条件;使用哪里