我需要在 ORDER BY 字段上添加索引吗?

问题描述 投票:0回答:8

我有这样的疑问

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

我需要在

comment_time
字段上添加索引吗?

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

mysql sql database-indexes
8个回答
32
投票

是的,当使用 ORDER BY 时,索引会帮助你。因为INDEX是排序的数据结构,所以请求会执行得更快。

看这个例子:表 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行并输出结果。 创建索引后,我们得到:

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 仅使用 1 行。

回答收到的评论,我尝试了没有限制的相同查询:

-- ----------------------------
-- 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

正如我们所见,它使用索引作为第二个

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


14
投票

comment_time
字段上的索引对于这样的查询可能根本没有帮助:

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

查询需要扫描表以查找匹配的

id
值。它可以通过扫描索引、查找行并进行测试来完成此操作。如果有一行匹配并且具有最高位
comment_time
,那么这需要扫描索引并读取表。

如果没有索引,它会扫描表,找到该行,然后非常快速对第一行进行排序。表的顺序扫描通常比索引扫描和页面查找更快(并且在大于可用内存的表上肯定会更快)。

另一方面,

id, comment_time
上的索引会非常有帮助。


1
投票

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

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

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


0
投票

您的问题和您的查询并不真正匹配。您只能通过该 id 获得结果,如果有 1 个结果则无需排序。

如果您想要 2 个日期之间的结果,则更像是

$query = "SELECT * FROM tbl_comments WHERE (comment_time BETWEEN '2010-01-30 14:15:55' AND '2010-09-29 10:15:55');

查询应该首先查找索引,所以如果 id 是 PK 那么是的 comment_time 应该被索引。

否则将它们一起索引 id 1 和 comment_time 2


-1
投票

如果你的where id是不同的,你不必将索引放在comment_time上。


-1
投票

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

编辑

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

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

通常很难确定“我是否需要索引”。

EXPLAIN
声明提供了一些帮助(参考手册)。


-1
投票

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

WHERE
BETWEEN
子句。

参考:http://www.w3schools.com/sql/sql_ Between.asp

© www.soinside.com 2019 - 2024. All rights reserved.