【发布时间】:2018-05-08 08:46:05
【问题描述】:
我有一种情况,我在数据库表中有几十万行,比如说 8 列,其中前两列被索引(每列两个索引,两列一个复合索引),我有两个带有 group by 和 union 的 SQL 查询:
SELECT MIN(columnOne), columnTwo FROM MyTable
WHERE columnTwo IN (1,2,3)
GROUP BY columnTwo
和
SELECT MIN(columnOne), columnTwo FROM MyTable WHERE columnTwo = 1
UNION
SELECT MIN(columnOne), columnTwo FROM MyTable WHERE columnTwo = 2
UNION
SELECT MIN(columnOne), columnTwo FROM MyTable WHERE columnTwo = 3
而且,使用 unions 的第二种方法的效果似乎比第一种方法快 两倍(有时更多)。
我在 Python 中执行这个查询,所以第一个是一个衬垫,第二个是我需要生成的。
我想知道第二种方法是否正常,可能还有第三种我不知道的方法?
更新:
所有查询中的columnTwo 和 columnOne 字段不是唯一的
例子
# columnOne columnTwo
1 a a
2 b b
3 c b
4 d a
...
用 group by 解释查询:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE MyTable index secondColIndex,bothColIndex bothColIndex 12 1623713 Using where
Explain for query with unions 显示如下:
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY MyTable ref secondColIndex,bothColIndex bothColIndex 4 const 217472 Using where
2 UNION MyTable ref secondColIndex,bothColIndex bothColIndex 4 const 185832 Using where
3 UNION MyTable ref secondColIndex,bothColIndex bothColIndex 4 const 175572 Using where
UNION RESULT <union1,2,3> ALL Using temporary
MyTable 中的索引:
Table, Non_unique, Key_name, Seq_in_index, Column_name, Collation, Cardinality, Sub_part, Packed, Null, Index_type, Comment, Index_comment
MyTable, 0, PRIMARY, 1, Id, A, 1623713, , , , BTREE, ,
MyTable, 1, columnOneIndex, 1, columnOne, A, 1623713, , , , BTREE, ,
MyTable, 1, columnTwoIndex, 1, columnTwo, A, 5737, , , , BTREE, ,
MyTable, 1, bothColumnsIndex, 1, columnTwo, A, 5171, , , , BTREE, ,
MyTable, 1, bothColumnsIndex, 2, columnOne, A, 1623713, , , , BTREE, ,
【问题讨论】:
-
好问题。冷/热数据差异?
-
但是您的查询不一样 - 带有“union”的查询选择了 3 条记录(并且在那里使用 min 没有意义,因为我们通过 id 选择了一条记录,我是假设
id是唯一的),而第一个选择 1 条宽度最小的记录。 -
我认为即使
id不是唯一的,由于“联合”查询,您仍然会得到 3 行,因此您实际上并没有得到一个min值,但是每组 3 个最小值。 -
是的,我需要为每个组获取 3 行最小值
-
我看起来像“group by”查询扫描了 160 万条记录,而联合查询中的“rows”总和大约为 500K(少三倍)。两列的索引如何?根据this,您可能需要它是
(columnTwo, columnOne)- 顺序很重要,columnTwo应该排在第一位。
标签: mysql sql select group-by union