【问题标题】:MySQL Multiple column indexMySQL 多列索引
【发布时间】:2016-10-03 19:14:16
【问题描述】:

好的,我有以下 MySQL 表结构:

CREATE TABLE `creditlog` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `memberId` int(10) unsigned NOT NULL,
  `quantity` decimal(10,2) unsigned DEFAULT NULL,
  `timeAdded` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `reference` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `memberId` (`memberId`),
  KEY `timeAdded` (`timeAdded`));

我这样查询它:

SELECT SUM(quantity) FROM creditlog where timeAdded>'2016-09-01' AND timeAdded<'2016-10-01' AND memberId IN (3,6,8,9,11)

现在,我也使用use index (timeAdded),因为由于条目的数量,它更方便。解释上述查询显示:

type -> range,
key -> timeAdded,
rows -> 921294
extra -> using where

同时,如果我使用 memberId INDEX,它会显示:

type -> range,
key -> memberId,
rows -> 1707849
extra -> using where

现在,我的问题是有可能以某种方式将这两个索引组合在一起使用并减少查询的表面,因为我还需要添加更多条件(在其他列上)。

【问题讨论】:

  • 是否要创建(timeAdded, memberId)的索引。
  • 我有兴趣弄清楚实际的顺序
  • 你测试了吗?
  • 尝试以两种方式添加复合索引,(memberId,timeAdded) 和 (timeAdded,memberId)。两者似乎都改善了查询。不确定哪个表现更好。
  • 检查基数对你有帮助

标签: mysql database indexing


【解决方案1】:

MySQL 几乎从不在一个查询中使用两个索引;它只是不划算。但是,复合索引通常非常有效。您需要这个订单:INDEX(memberId, timeAdded)

以这种方式构建索引...

  1. 首先包括在WHERE 子句中使用= 测试的列。 (没有,在你的情况下。)
  2. 任何带有IN 的列。
  3. 一个“范围”,例如&lt;BETWEEN等。
  4. 移动到GROUP BYORDER BY 的所有字段。 (此处不相关。)

有很多例外和警告。有些在我的cookbook 中给出。

(与流行观点相反,基数几乎与设计索引无关。)

这是一种比较两个索引的方法(即使表太小而无法获得可靠的时序):

FLUSH STATUS;
SELECT SQL_NO_CACHE ...;
SHOW SESSION STATUS LIKE 'Handler%';
(repeat for other query/index)

数字越小越好。

"timeAdded>'2016-09-01' AND timeAdded

    timeAdded >= '2016-09-01'
AND timeAdded  < '2016-09-01' + INTERVAL 1 MONTH

这也避免了计算日期。

这闻起来像一个常见的查询?您是否考虑过构建和维护Summary tables?等效查询的运行速度可能会快 10 倍。

【讨论】:

    猜你喜欢
    • 2016-09-12
    • 1970-01-01
    • 2011-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-09
    • 1970-01-01
    相关资源
    最近更新 更多