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

Mun*_*nib 9 php mysql sql

我有这样的查询

$query = "SELECT * FROM tbl_comments WHERE id=222 ORDER BY comment_time";
Run Code Online (Sandbox Code Playgroud)

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

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

Gor*_*off 8

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

SELECT *
FROM tbl_comments
WHERE id=222
ORDER BY comment_time;
Run Code Online (Sandbox Code Playgroud)

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

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

另一方面,索引id, comment_time将非常有帮助。


use*_*035 7

是的,当使用ORDER BY时,index会帮助您.因为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)
Run Code Online (Sandbox Code Playgroud)

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)
Run Code Online (Sandbox Code Playgroud)

现在MySQL只使用了1行.

回答收到的评论,我尝试了相同的查询,没有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
Run Code Online (Sandbox Code Playgroud)

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

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

CREATE INDEX ix_comment_time ON tbl_comments (comment_time) USING BTREE;
Run Code Online (Sandbox Code Playgroud)

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

  • @Strawberry是的,因为如果你在索引创建之前看一下解释,它会说:"额外:使用filesort".之后 - "使用索引".当MySQL无法使用索引生成排序结果时,它必须对行本身进行排序.它可以在内存或磁盘上执行此操作,但它始终将此进程称为filesort(取自High Performance MySQL).因此,它不会在第二种情况下对记录进行排序,并且必须更快地执行请求. (2认同)

Voi*_*cus -1

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

编辑

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

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

通常很难确定“我是否需要索引”。语句提供了一些帮助EXPLAIN请参阅手册)。