这个 MySQL 查询的最佳复合索引是什么?

What would be the best compound index for this MySQL query?

这个 MySQL 查询的最佳复合索引是什么?

SELECT 
    c.id, c.customer_id, c.service_id, c.origin_id, c.title, c.state, c.start_date_time
FROM 
    calendar_events c
WHERE 
    c.customer_id = 1234
    AND c.state IN ('unconfirmed', 'confirmed')
    AND c.start_datetime BETWEEN '2016-10-15 00:00:00' AND '2016-10-15 23:59:59';

可能是这样的:

INDEX(customer_id,    -- '=' comes first
      state,          -- 'IN' sometimes works ok in the middle
      start_datetime) -- nothing after a 'range' will be used

运行 EXPLAIN SELECT ... 大概会在Other栏里说"MRR"。我称之为 'leapfrog' 优化。在您的情况下,它很容易到达索引行的开头 1234 & 'unconfirmed' & 00:00。然后它将扫描当天的连续条目。

然后它将跳到 1234 & 'confirmed' & 00:00 进行另一次扫描。

这增加了对索引的两次 BTree 探测,以及两次索引扫描。效率很高。

然后,对于索引中的每一行,它将遍历(使用 PRIMARY KEY)以获取所需的其他列。

日期和时间范围的推荐模式:

AND c.start_datetime >= '2016-10-15'
AND c.start_datetime  < '2016-10-15' + INTERVAL 1 DAY