MySQL文檔在section 11.5.3中聲明,儘管SQL標準可能會說,但使用列在SELECT子句中不在GROUP BY子句中,只要它們在功能上依賴於分組鍵。MySQL聲稱我可以在SELECT中使用不在GROUP BY中的列,但我不能以相同的性能
MySQL的擴展使用GROUP BY的這樣 可以使用非聚合列 或計算在選擇列表 沒有出現在GROUP BY子句 。您可以使用此功能 通過避免 不必要的列排序和 分組獲得更好的性能。例如,你不需要下面的查詢在 上customer.name 組:
SELECT order.custid, customer.name, MAX(payments) FROM order,customer WHERE order.custid = customer.custid GROUP BY order.custid;
在標準 SQL,你將不得不 customer.name添加到GROUP BY子句。 在MySQL中,名稱是多餘的。
聽起來很合理。但是,雖然我可以選擇這些列,但它似乎對性能有不利影響。
EXPLAIN SELECT o.id FROM objects o GROUP BY o.id;
+----+-------------+-------+-------+---------------+---------+---------+------+------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+---------------+---------+---------+------+------+--------------------------+
| 1 | SIMPLE | o | range | NULL | PRIMARY | 3 | NULL | 5262 | Using index for group-by |
+----+-------------+-------+-------+---------------+---------+---------+------+------+--------------------------+
(我意識到,這個查詢是非常愚蠢的。它只是一個更復雜的查詢具有相同問題的最簡單的版本)當只選擇主鍵ID I組,那麼MySQL使用主關鍵指標。但是,當我包含其他列時,MySQL不會。
EXPLAIN SELECT o.id, o.name FROM objects o GROUP BY o.id;
+----+-------------+-------+------+---------------+------+---------+------+------+----------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+------+------+----------------+
| 1 | SIMPLE | o | ALL | NULL | NULL | NULL | NULL | 5261 | Using filesort |
+----+-------------+-------+------+---------------+------+---------+------+------+----------------+
使用filesort而不是索引真的讓我回想起來。我目前希望從該表中選擇*
,所以希望避免重複組中的所有列並將它們編入索引。有沒有什麼辦法讓MySQL使用主鍵索引,就像我期望的那樣?
我可以在技術上使用子查詢和派生表,但目前形式的MySQL優化器(至少在Debian存儲庫的最新版本中)將它們視爲從屬子查詢,而不是提前運行,然後運行反對。我敢打賭,這是因爲它是具有不同別名的同一張桌子。 – Matchu 2010-11-19 19:29:16