MySQL:用于简单范围选择的索引是什么?

时间:2010-09-14 14:38:59

标签: sql mysql select indexing range

我有一个约3000万行(并且还在增长!)的表格,目前我在一个简单的范围选择方面遇到了一些问题。

查询,如下所示:

SELECT SUM( CEIL( dlvSize / 100 ) ) as numItems
FROM log
WHERE timeLogged BETWEEN 1000000 AND 2000000
AND user = 'example'</pre>

完成需要几分钟,我认为解决方案将在我正在使用的索引处。以下是解释结果:

+----+-------------+-------+-------+---------------------------------+---------+---------+------+----------+-------------+
| id | select_type | table | type  | possible_keys                   | key     | key_len | ref  | rows     | Extra       |
+----+-------------+-------+-------+---------------------------------+---------+---------+------+----------+-------------+
|  1 | SIMPLE      | log   | range | PRIMARY,timeLogged              | PRIMARY | 4       | NULL | 11839754 | Using where | 
+----+-------------+-------+-------+---------------------------------+---------+---------+------+----------+-------------+

我的表结构就是这个(减少使其更适合问题):

CREATE TABLE IF NOT EXISTS `log` (
  `origDomain` varchar(64) NOT NULL default '0',
  `timeLogged` int(11) NOT NULL default '0',
  `orig` varchar(128) NOT NULL default '',
  `rcpt` varchar(128) NOT NULL default '',
  `dlvSize` varchar(255) default NULL,
  `user` varchar(255) default NULL,
  PRIMARY KEY  (`timeLogged`,`orig`,`rcpt`),
  KEY `timeLogged` (`timeLogged`),
  KEY `orig` (`orig`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

我可以做些什么来优化我的桌面上的查询或索引?

3 个答案:

答案 0 :(得分:3)

您可以尝试在(user, timeLogged)上添加composite index

CREATE TABLE IF NOT EXISTS `log` (
  ...
  KEY `user_timeLogged` (user, timeLogged),
  ...
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

相关Stack Overflow帖子:

答案 1 :(得分:1)

除了其他答案提出的建议外,我还注意到表格中有一列uservarchar(255)。如果这引用了用户表中的列,则1)最有可能将整数ID列添加到该表中,并将其用作主键和其他表中的引用列; 2)您正在使用InnoDB,那么为什么不利用它提供的外键功能呢?

如果您按varchar(n)列进行索引,则会将其视为索引中的char(n),因此当前主键的每一行占用4 + 128 + 128 = 260字节索引。

答案 2 :(得分:0)

user上添加索引。