我有以下MySQL查询需要一天以上的时间来执行:
SELECT SN,NUMBER FROM a
WHERE SN IN
(SELECT LOWER_SN FROM b
WHERE HIGHER_ED LIKE "%c1" AND LOWER_ED LIKE "%16")
AND ED LIKE "%16"
子查询需要21秒才能运行,并返回11035行。我有一个索引:
SHOW INDEX FROM a
表非唯一键名Seq_in_index列名归类基数子部分填充空Index_type注释Index_comment
0 a 1 wob1 1 ED A 756095无无BTREE
1 a 1 wob2 1 SN A 2268287无无BTREE
2 a 1 wob3 1 ED A 756095无无BTREE
3 a 1 wob3 2 SN A 9073150无无BTREE
4 a 1 wob4 1号码A 18146301无无是BTREE
5 a 1 wob5 1 SN A 2268287无无BTREE
6 a 1 wob5 2号码A 18146301无无是BTREE
EXPLAIN
给出:
#id,select_type,表,类型,可能的键,键,key_len,ref,行,额外
'1','PRIMARY','a','ALL',NULL,NULL,NULL,NULL,'18146301','在哪里使用'
'2','DEPENDENT SUBQUERY','b','index_subquery','cfg2','cfg2','47','func','6','在何处使用
为什么不使用索引?如何加快查询速度?
答案 0 :(得分:1)
alloca
出于多种原因,我通常不支持相关子查询;但由于您无法从索引中受益,因此此可能可以解决。
它将为每个SELECT a.SN, a.NUMBER
FROM a
WHERE EXISTS (
SELECT *
FROM b
WHERE b.LOWER_SN = a.SN
AND b.HIGHER_ED LIKE "%c1"
AND b.LOWER_ED LIKE "%16"
)
AND a.ED LIKE "%16"
记录在后台有效地运行子查询(或者如果查询优化器正在帮助,则可能只有与a
条件匹配的a
条记录)。通常,这会更昂贵;但是a.ED LIKE
子查询的运行速度比以前的子查询快得多,因为它只需要评估具有特定LOWER_SN值的EXISTS
记录,并且EXISTS在找到单个匹配项时将其“提前排除”而不是找到每一个匹配项。您应该为b
编制索引,以确保尽快识别每个b.LOWER_SN
条记录的b
条记录。
如果以上版本仍然很慢,则可能值得尝试:
a
如果优化器不这样做,它基本上只会首先强制在SELECT a2.SN, a2.NUMBER
FROM (SELECT a.SN, a.NUMBER FROM a WHERE AND a.ED LIKE "%16") AS a2
WHERE EXISTS (
SELECT *
FROM b
WHERE b.LOWER_SN = a2.SN
AND b.HIGHER_ED LIKE "%c1"
AND b.LOWER_ED LIKE "%16"
)
条件下过滤表。