0

我有以下 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

Table Non_unique Key_name Seq_in_index Column_name Collat​​ion Cardinality Sub_part Packed Null Index_type Comment 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 NUMBER A 18146301 无 无 是 BTREE
5 a 1 wob5 1 SN A 2268287 无 无 BTREE
6 a 1 wob5 2 编号 A 18146301 无 无 是 BTREE

EXPLAIN给出:

# id, select_type, table, type, possible_keys, key, key_len, ref, rows, Extra

'1', 'PRIMARY', 'a', 'ALL', NULL, NULL, NULL, NULL, '18146301', '使用 where'

'2', 'DEPENDENT SUBQUERY', 'b', 'index_subquery', 'cfg2', 'cfg2', '47', 'func', '6', '使用 where'

为什么不使用索引?如何加快查询速度?

4

1 回答 1

1
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条件的记录)。通常,这会更昂贵;但是EXISTS子查询可以比您之前的子查询运行得快得多,因为它只需要评估b具有特定 LOWER_SN 值的记录,并且 EXISTS 在找到单个匹配项而不是找到每个匹配项时给它一个“提前退出”。您应该编制索引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"
)

a.ED LIKE如果优化器不这样做,它基本上只是强制首先根据条件过滤表。

于 2018-06-20T22:08:07.693 回答