【发布时间】:2019-10-30 11:08:41
【问题描述】:
组合查询
select a, b from A where a > 5 and b in (select b from B where c = "some")
大约比固定查询长 30 倍
select a, b from A where a > 5 and b in (1, 2, 3)
虽然
-
select b from B where c = "some"产生与固定查询中使用的完全相同的行集,(1, 2, 3) -
select b from B where c = "some"单独执行需要 0.01 秒 -
select a, b from A where a > 5执行需要 0.3 秒。
A 上的 (a, b) 上有一个索引。
分析组合查询:
analyze select a, b from A where a > 5 and b in (select b from B)
*************************** 1. row ***************************
id: 1
select_type: PRIMARY
table: A
type: range
possible_keys: idx_a_b
key: idx_a_b
key_len: 8
ref: NULL
rows: 126459
r_rows: 66181.00
filtered: 100.00
r_filtered: 100.00
Extra: Using index condition; Using temporary; Using filesort
*************************** 2. row ***************************
id: 1
select_type: PRIMARY
table: B
type: eq_ref
possible_keys: PRIMARY
key: PRIMARY
key_len: 2
ref: A.b
rows: 1
r_rows: 1.00
filtered: 100.00
r_filtered: 0.09
Extra: Using where
请注意,r_rows = 66181 匹配 select a, b from A where a > 5。
似乎 MariaDB 仅使用索引的 a 部分而忽略了它应该能够在第一步中从子查询中获取的 b。解释扩展显示 MariaDB 用
替换了我的查询select b, a from B join A where ((B.b = A.b) and (A.a > 5) and (B.c = "some"))
奇怪的是,如果给定子查询返回的固定集合 (1, 2, 3),而不是子查询本身,MariaDB 确实似乎确实同时使用了索引的 a 和 b,因为可以通过分析固定查询观察到:
analyze select a, b from A where a > 5 and y in (1, 2, 3)
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: A
type: range
possible_keys: idx_a_b
key: idx_a_b
key_len: 10
ref: NULL
rows: 126459
r_rows: 59.00
filtered: 100.00
r_filtered: 100.00
Extra: Using index condition; Using temporary; Using filesort
r_rows = 59 匹配两个查询(组合查询和固定查询)的结果集大小。
如何让 MariaDB 使用与固定查询相同的查询计划,同时使用 A 的索引中的 a 和子查询的 b?
【问题讨论】:
-
什么版本??这方面已经有所改进。
-
10.1.40-MariaDB-0ubuntu0.18.04.1
标签: mysql sql indexing subquery mariadb