我是否需要在ORDER BY字段中添加索引?

时间:2013-05-28 12:43:00

标签: php mysql sql

我有类似

的查询
$query = "SELECT * FROM tbl_comments WHERE id=222 ORDER BY comment_time";

我是否需要在comment_time字段上添加索引?

另外,如果我想在两个日期之间获取数据,那么我应该如何构建索引?

7 个答案:

答案 0 :(得分:7)

是的,索引会在使用ORDER BY时帮助您。因为INDEX是一个排序的数据结构,所以请求将更快地执行。

看一下这个例子:table test2有3行。我在order by之后使用LIMIT来显示执行的差异。

DROP TABLE IF EXISTS `test2`;
CREATE TABLE `test2` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `value` varchar(10) CHARACTER SET utf8 COLLATE utf8_swedish_ci NOT NULL,
  PRIMARY KEY (`id`),
  KEY `ix_value` (`value`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of test2
-- ----------------------------
INSERT INTO `test2` VALUES ('1', '10');
INSERT INTO `test2` VALUES ('2', '11');
INSERT INTO `test2` VALUES ('2', '9');

-- ----------------------------
-- Without INDEX
-- ----------------------------

mysql> EXPLAIN SELECT * FROM test2 ORDER BY value LIMIT 1\G
*************************** 1. row *************************
           id: 1
  select_type: SIMPLE
        table: test2
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 3
        Extra: Using filesort
1 row in set (0.00 sec)

MySQL检查了3行以输出结果。 在CREATE INDEX之后,我们得到了这个:

mysql> CREATE INDEX ix_value ON test2 (value) USING BTREE;
Query OK, 0 rows affected (0.14 sec)

-- ----------------------------
-- With INDEX
-- ----------------------------

mysql> EXPLAIN SELECT * FROM test2 ORDER BY value LIMIT 1\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: test2
         type: index
possible_keys: NULL
          key: ix_value
      key_len: 32
          ref: NULL
         rows: 1
        Extra: Using index
1 row in set (0.00 sec)

现在MySQL只使用了一行。

回答收到的评论,我在没有LIMIT的情况下尝试了相同的查询:

-- ----------------------------
-- Without INDEX
-- ----------------------------

mysql> EXPLAIN SELECT * FROM test2 ORDER BY value\G
*************************** 1. row ******************
           id: 1
  select_type: SIMPLE
        table: test2
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 3
        Extra: Using filesort

-- ----------------------------
-- With INDEX
-- ----------------------------

mysql> EXPLAIN SELECT * FROM test2 ORDER BY value\G
*************************** 1. row *****************
           id: 1
  select_type: SIMPLE
        table: test2
         type: index
possible_keys: NULL
          key: ix_value
      key_len: 32
          ref: NULL
         rows: 3
        Extra: Using index

如我们所见,它使用索引,用于第2个ORDER BY

要在您的字段上构建索引,请使用以下命令:

CREATE INDEX ix_comment_time ON tbl_comments (comment_time) USING BTREE;

http://dev.mysql.com/doc/refman/5.0/en/create-index.html

答案 1 :(得分:1)

从技术上讲,你不需要每个字段的索引,因为它也可以工作,但是出于性能原因,你可能需要一个或多个。

修改

从软件设计之初就知道这个问题。通常,如果增加程序使用的内存量,则会降低其速度(假设程序编写良好)。为字段分配索引会增加数据库使用的数据,但会使搜索速度更快。如果你不想通过这个字段搜索任何东西(你实际上在问题中),那就没有必要了。

在现代,与磁盘数据大小相比,索引并不是那么大,添加一个或多个应该不是一个坏主意。

通常很难确定“我是否需要索引”。 EXPLAIN声明(refer to the manual)提供了一些帮助。

答案 2 :(得分:1)

关于第一个问题,您不必在comment_time上创建索引。如果记录数量非常大,您需要索引来加快检索速度。但对于您的操作,您不需要索引。 对于你的第二个问题,使用像这样的WHERE条款会对你有帮助。

WHERE(comment_time BETWEEN 'startDate' AND 'endDate');

答案 3 :(得分:1)

comment_time字段上的索引可能对此类查询完全没有帮助:

SELECT *
FROM tbl_comments
WHERE id=222
ORDER BY comment_time;

查询需要扫描表以查找匹配的id值。它可以通过扫描索引,查找行和进行测试来实现。如果有一行匹配并且它具有高位comment_time,则需要扫描索引并读取表格。

没有索引,它会扫描表格,找到行,非常快速排序1行。表的顺序扫描通常比索引扫描更快,然后是页面查找(并且在比可用内存大的表上肯定会更快)。

另一方面,id, comment_time上的索引会非常有用。

答案 4 :(得分:0)

如果您的where id不同,则不必将index_time放在index_time上。

答案 5 :(得分:0)

要提高检索数据的速度,您需要索引。这也适用于索引。对于第二个问题,您可以使用WHEREBETWEEN子句。

参考:http://www.w3schools.com/sql/sql_between.asp

答案 6 :(得分:0)

EXPLAIN语句在这种情况下非常有用。对于您的查询,您将按如下方式使用它:

EXPLAIN SELECT * FROM tbl_comments WHERE id=222 ORDER BY comment_time

这将输出正在使用哪些索引来执行查询,并允许您使用不同的索引执行实验以查找最佳配置。为了加快排序速度,您需要一个BTREE索引,因为它以排序的方式存储数据。为了加快查找具有特定id的项目,HASH索引是更好的选择,因为它提供了对等式谓词的快速查找。请注意,MySQL可能无法使用两个索引的组合来执行您的查询,而只会使用其中一个。

更多信息:http://dev.mysql.com/doc/refman/5.7/en/using-explain.html

对于范围谓词,例如日期范围内的日期,BTREE索引的性能优于HASH索引。

更多信息:http://dev.mysql.com/doc/refman/5.7/en/create-index.html