Ich benutze MySQL 5.6.19-Log (nach select version()
).Wie erzwinge MySQL "Verwenden von Index für Group-by"
Ich habe eine InnoDB-Tabelle etwas wie folgt aus:
CREATE TABLE `mytable` (
`foo_id` bigint(20) NOT NULL,
`bar_id` bigint(20) NOT NULL,
`baz_id` bigint(20) NOT NULL,
PRIMARY KEY (`foo_id`,`bar_id`,`baz_id`)
)
Diese Tabelle funktioniert gut mit der folgenden Abfrage:
select
foo_id,
min(bar_id)-1
from
mytable
where
foo_id IN (
1000,2000
)
group by
foo_id;
+----+-------------+----------------------+-------+------------------------+---------+---------+------+-------+---------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+----------------------+-------+------------------------+---------+---------+------+-------+---------------------------------------+
| 1 | SIMPLE | mytable | range | PRIMARY,bar_id_idx | PRIMARY | 8 | NULL | 58245 | Using where; Using index for group-by |
+----+-------------+----------------------+-------+------------------------+---------+---------+------+-------+---------------------------------------+
+----------+------------+-----------------------------------------------------------------------------------------------------------------------------------------------+
| Query_ID | Duration | Query |
+----------+------------+-----------------------------------------------------------------------------------------------------------------------------------------------+
| 1 | 0.00036575 | select foo_id, min(bar_id)-1 from mytable where foo_id IN (1000,2000) group by foo_id |
+----------+------------+-----------------------------------------------------------------------------------------------------------------------------------------------+
Aber, wenn die Anzahl der foo_id
in der where-Klausel ist nur , die Abfrage wird ziemlich langsam, wie folgt:
select
foo_id,
min(bar_id)-1
from
mytable
where
foo_id = 1000
group by
foo_id;
+----+-------------+----------------------+------+------------------------+---------+---------+-------+--------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+----------------------+------+------------------------+---------+---------+-------+--------+-------------+
| 1 | SIMPLE | mytable | ref | PRIMARY,bar_id_idx | PRIMARY | 8 | const | 873664 | Using index |
+----+-------------+----------------------+------+------------------------+---------+---------+-------+--------+-------------+
+----------+------------+-----------------------------------------------------------------------------------------------------------------+
| Query_ID | Duration | Query |
+----------+------------+-----------------------------------------------------------------------------------------------------------------+
| 1 | 0.07258075 | select foo_id, min(bar_id)-1 from mytable where foo_id = 1000 group by foo_id |
+----------+------------+-----------------------------------------------------------------------------------------------------------------+
Ich denke, etwas wen t falsch mit dem Abfrageplaner von MySQL. Gibt es einen Hinweis oder etwas, um MySQL zu zwingen, den Index für die Gruppe zu verwenden, wenn die Nummer foo_id
nur eine ist? Ich habe versucht analyze table mytable
, aber es hilft nicht.
Ich weiß, dass eine Abfrage select min(bar_id)-1 from mytable where foo_id = 1000
ist schnell, wenn die Nummer foo_id
ist nur eine, aber es macht eine Verzweigung zum Code meiner App, also möchte ich dies vermeiden.
es, wenn Sie 'wo foo_id in (1000)' tut helfen? – shmosel
Leider nicht. Es erzeugt genau den gleichen Abfrageplan und die gleiche Leistung wie 'wo foo_id = 1000' –
Was passiert, wenn Sie die' group by' entfernen? – shmosel