【发布时间】:2019-12-30 06:10:27
【问题描述】:
我知道这个问题之前已经被问过很多次了,但我已经尝试了那里提到的解决方案,但没有找到答案。 我不确定答案是否只是“不可能”,因此决定提出这个问题。
我有 2 张桌子,尺寸如下:
SELECT COUNT(*) from t1
24mill
SELECT COUNT(*) from t1 WHERE col1 = 1 and col2 = 'A';
395k
SELECT COUNT(*) from t2
6mill
SELECT COUNT(*) from t2 WHERE col3 != 'B';
5.9mill
注意:
-
col2和col3是只有 6 个唯一值的枚举。 -
col1是具有约 9000 个唯一值的外键 -
t1->t2是一对多 =>t1中的多个记录将链接到同一个t2。 - 这些列都不能为空
我想要做的查询是:
SELECT COUNT(*) AS num
FROM t1 INNER JOIN t2 ON t1.t2_ID = t2.t2_ID
WHERE t1.col1 = 1 AND t1.col2 = 'A' AND t2.col3 != 'B';
395k
t2_ID 是 t2 的主键,是 t1 的外键。
我已经创建了索引:
ALTER TABLE t1 ADD KEY key1 (t2_id);
ALTER TABLE t1 ADD KEY key2 (col1, t2_id, col2);
解释:
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: t1
partitions: NULL
type: ref
possible_keys: key1,key2
key: key2
key_len: 4
ref: const
rows: 660k
filtered: 50.00
Extra: Using where; Using index
*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: t2
partitions: NULL
type: eq_ref
possible_keys: PRIMARY,key3,key4
key: PRIMARY
key_len: 4
ref: t1.t2_ID
rows: 1
filtered: 85.71
Extra: Using where
当我运行这个查询时,它需要 3 秒。我正在尝试弄清楚如何才能使这更快。
在我看来,它已经在使用索引了。我正在尝试查看是否可以制作更好的索引或子查询或其他东西以使其更快。
【问题讨论】:
-
面对现实,爬过 395K 行需要时间。 3 秒听起来很快。
-
悲伤,但可能是真的。不过,我很想了解 3sec 的原因/原因。从某种意义上说——在这种情况下,我应该寻求改进哪些基础设施参数。我能理解 3 秒中有多少时间是因为数据加载(即来自 Amazon 的高 IOPS 磁盘会有所帮助吗?)还是仅仅是 RAM 周期(内存优化实例),或者可能只是 CPU - 或全部!如果没有软件解决方案有效,我可能不得不进行硬件优化
-
什么版本的 MySQL?我认为较新的版本可以一些使用
!=(但不是按照您用于索引的顺序)。 -
5.7 - 我可以升级到最新的次要版本。由于很多原因,我必须使用 5.x。我目前在 Mac OSX 上使用 5.7.26
-
@TimBiegeleisen - MySQL 几乎总是使用“NLJ”(嵌套循环连接)。首先,它查看一个表(过滤掉不需要的行)。然后对于这些行中的每一行,它会到达下一个表。 (哪个表先出现是一种优化。)
标签: mysql sql join query-optimization