mysql - 如何为查询设置连接和分组索引

标签 mysql join indexing

假设我们有一个如下所示的通用连接:

EXPLAIN SELECT *  
FROM visited_links vl
JOIN device_tracker dt ON ( dt.Client_id = vl.Client_id
AND dt.Device_id = vl.Device_id ) 
GROUP BY dt.id

如果我们执行解释,它说:

id  select_type   table   type    possible_keys           key        key_len   ref                         rows   Extra
1   SIMPLE        vl      index   NULL                    vl_id      273       NULL                        1977   Using index; Using temporary; Using filesort
1   SIMPLE        dt      ref     Device_id,Device_id_2   Device_id  257       datumprotect.vl.device_id   4      Using where

我知道有时在使用 group by 时很难选择正确的索引,但是,我可以设置哪些索引来避免在此查询中“使用临时文件,使用文件排序”?为什么会这样?特别是,为什么在使用索引后会发生这种情况?

最佳答案

需要提及的一点是,select(在本例中为 *)返回的字段应该在 GROUP BY 子句中或使用聚合函数,例如 SUM() 或 MAX()。否则可能会出现意想不到的结果。这是因为如果数据库没有被告知如何选择不在 group by 子句中的字段,您可能会随机获得该组的任何成员。


我看待它的方式是将查询分解成位。

  1. 您有一个连接(dt.Client_id = vl.Client_id 和 dt.Device_id = vl.Device_id),因此所有这些字段都应该在各自的表中建立索引。

  2. 您正在使用 GROUP BY dt.id,因此您需要一个包含 dt.id 的索引

但是...

(dt.client_id,dt.device_id,dt.id) 上的索引不适用于 GROUP BY

(dt.id, dt.client_id, dt.device_id) 上的索引不适用于连接。

有时您最终会得到一个无法使用索引的查询。

另见: http://ntsrikanth.blogspot.com/2007/11/sql-query-order-of-execution.html

关于mysql - 如何为查询设置连接和分组索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5552319/

相关文章:

indexing - openssl 的字段数量错误

c - PostgreSQL:如何实现 GIN?

MATLAB 组合不同维度的矩阵,填充相应索引的值

mysql - LEFT OUTER JOIN 出现问题

mysql - 关于比较两个索引 : (a, b) 和 (a)

MySQL 使用 Case 语句确定下一个季度(当最后一个季度为 4 时)

php - 两个表的内连接

php - WordPress:将 wp_users 和 wp_metadata 中的所有关联元数据选择到每个用户记录的一行中

php - codeigniter 如何在单个 View 中加载两个不同的 mysql 表列表

mysql - 带有 COUNT 的子查询 (mysql)