2016-10-03 80 views
0

好吧,我有以下MySQL表结构: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 

现在,我的问题是,它可能这两个指标在某种程度上结合起来一起使用,降低了因为我还需要添加更多条件(在其他列上)。

+0

是你想创建(timeAdded,memberId)的索引。 – khalid

+0

我有兴趣确定订单实际上 – Samson

+0

您测试过吗? – khalid

回答

0

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

建立索引这样...

  1. 首先包括与=测试WHERE子句中的列(S)。 (无,你的情况。)
  2. 任何列与IN
  3. 一个 '范围',如<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 <'2016-10-01'” - 这不包括第一天的午夜。我推荐这种模式:

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

这也避免了计算日期。

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