【问题标题】:Can indexes on multiple 'range' columns be utilized?可以使用多个“范围”列上的索引吗?
【发布时间】:2015-05-12 16:33:37
【问题描述】:

我有这个索引:

alter table wx_cbmessage add index main_query (cbm_owner_id,cbm_status,cbm_date,cbm_notification_date);

这个查询:

SELECT SQL_CALC_FOUND_ROWS ... 
FROM `wx_cbmessage` `msg` FORCE INDEX (main_query) 
    LEFT JOIN wx_user `from` ON cbm_from_user_id=from.login 
WHERE `cbm_owner_id`='username' 
    AND cbm_date <= 1431448013 
    AND (`cbm_notification_date`=0 OR cbm_notification_date <= 1431448013) 
    AND `cbm_status`=1 
ORDER BY `cbm_date` DESC 
LIMIT 25

cbm_notification_date 作为索引的一部分有什么意义吗?可以用吗?

前两列只是完全匹配,但我不知道 MySQL 是否可以对多个范围搜索进行任何操作。

【问题讨论】:

  • 解释告诉你什么?
  • @Strawberry 不多。它告诉我它正在使用索引,但不是索引的哪些部分。 ref 实际上是 NULL 当我使用 FORCE INDEX 但如果我不强制它说 const,const,我认为这意味着前两列是恒定时间查找 - 这是否意味着其他两列不是根本没用过还是什么?

标签: mysql optimization indexing


【解决方案1】:

请使用表别名限定列名。不知道哪一列是哪张表,我只好猜测如何给建议。

两个范围 -- 不会被使用。

EXPLAIN 无法解释 -- 试试EXPLAIN FORMAT=JSON SELECT ...

我推荐这个(因为列都在同一个表中):

INDEX(cbm_owner_id, cbm_status, cbm_date)

它可以用于 2 个常量和一个范围。它可以用于ORDER BY。 优化器没有很好的方法来选择使用哪一个。

(`cbm_notification_date`=0 OR cbm_notification_date <= 1431448013) 

由于OR 和“范围”的组合,无法使用索引。 (x=1 OR x=3) 等价于 (x IN (1,3)),比范围好,虽然不如常量。

【讨论】:

  • 对不起,date cbm_date,这是一个unix时间戳(BIGINT)。有两个索引有什么意义?我以为 MySQL 每个表只能使用一个?
  • 提供多个索引给了优化器一个选择——对一组值使用一个索引;等等。我将编辑我的答案以拥有一个索引,因为该字段是相同的。
  • 哇。 EXPLAIN FORMAT=JSON 提供了更多信息。我不知道那个功能。谢谢!
猜你喜欢
  • 2013-11-30
  • 2020-11-06
  • 1970-01-01
  • 1970-01-01
  • 2012-06-28
  • 2019-02-08
  • 2016-08-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多