正确的MySQL查询索引

时间:2011-09-27 10:58:50

标签: mysql indices

我有以下表格:

  CREATE TABLE `sal_forwarding` (
  `sid` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
  `f_shop` INT(11) NOT NULL,
  `f_offer` INT(11) DEFAULT NULL,
  .
  .
  .
  PRIMARY KEY (`sid`),
  KEY `forwardTime` (`forwardTime`,`f_shop`),
  KEY `forwardTime_2` (`forwardTime`),
  KEY `f_shop` (`f_shop`)
) ENGINE=INNODB AUTO_INCREMENT=10457068 DEFAULT CHARSET=latin1

此表有超过500万行。

我已经设置了索引,如上所示,但在我的查询中没有使用索引,我不明白为什么。有人看到我的问题吗?

说明:

EXPLAIN SELECT 
  f_shop
  , COUNT(sid)
  , SUM(IF(toolbarUser=1,1,0)) 
FROM sal_forwarding 
WHERE DATE(forwardTime) = "2011-09-01" 
GROUP BY f_shop

结果:

+----+-------------+----------------+-------+---------------+--------+---------+--------+--------+-------------+
| ID | SELECT_TYPE |     TABLE      | TYPE  | POSSIBLE_KEYS |  KEY   | KEY_LEN |  REF   |  ROWS  |    EXTRA    |
+----+-------------+----------------+-------+---------------+--------+---------+--------+--------+-------------+
|    |             |                |       |               |        |         |        |        |             |
| 1  | SIMPLE      | sal_forwarding | index | (NULL)        | f_shop | 4       | (NULL) | 232449 | Using where |
+----+-------------+----------------+-------+---------------+--------+---------+--------+--------+-------------+

1 个答案:

答案 0 :(得分:2)

MySQL不能在函数内的列上使用索引 从select中删除函数date(),MySQL将使用索引。

您可以通过将forwardtime的列定义更改为DATE来实现此目的 或者您可以像这样更改查询

SELECT 
  f_shop
  , COUNT(*) as RowCount
  , SUM(toolbarUser=1) as NumberOfToolbarUsers
FROM sal_forwarding 
WHERE forwardTime BETWEEN '2011-09-01 00:00' AND '2011-09-01 23:59' 
GROUP BY f_shop

备注

  • count(*)count(namedcolumn)快;
  • (a = 1)=> 1如果为真,(a = 1)=> 0如果为false,则可以缩短if(a=1,1,0);
  • 为您的聚合列添加别名是个好主意,因此您可以稍后通过别名引用它们。
  • 如果添加以下索引(并删除索引forwardtime),则查询将运行得更快。 KEY fasttime (forwardTime,f_shop,toolbarUser)
  • 之前的观点尤其适用于InnoDB,如果可能,MySQL将使用覆盖索引,这意味着如果它能够在索引中找到它所需的全部内容,它将永远不会读取表本身来检索数据。