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

00jrzges  于 2023-02-03  发布在  Mysql
关注(0)|答案(7)|浏览(630)

我有一个这样的疑问

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

是否需要在comment_time字段上添加索引?
另外,如果我想获得两个日期之间的数据,那么我应该如何建立索引?

monwx1rj

monwx1rj1#

是的,当使用ORDER BY时,索引会帮助你。因为索引是一个排序的数据结构,所以请求会执行得更快。
看这个例子:表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只使用了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

如我们所见,它使用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

6rqinv9w

6rqinv9w2#

comment_time字段上的索引可能对以下查询毫无帮助:

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

查询需要扫描表以查找匹配的id值。它可以通过扫描索引、查找行和执行测试来完成此操作。如果有一行匹配并且具有highext comment_time,则需要扫描索引并阅读表。
如果没有索引,它将扫描表,找到行,并 * 非常 * 快速地对1行进行排序,顺序扫描表通常比索引扫描后进行页面查找更快(并且在大于可用内存的表上肯定更快)。
另一方面,id, comment_time上的索引将非常有用。

f2uvfpb9

f2uvfpb93#

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

    • 编辑**

这个问题在软件设计之初就已经知道了。通常,如果你增加了程序使用的内存量,你会降低它的速度(假设程序写得很好)。给一个字段分配一个索引会增加数据库使用的数据,但是会使搜索更快。如果你不想通过这个字段搜索任何东西(你在问题中实际上是这样做的),那就没有必要了。
在现代的索引不是那么大相比磁盘数据大小和添加一个或多个应该不是一个坏主意。
通常很难确定"我是否需要索引"。EXPLAIN语句(refer to the manual)提供了一些帮助。

gev0vcfq

gev0vcfq4#

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

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

2eafrhcq5#

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

igsr9ssn

igsr9ssn6#

为了提高检索数据的速度,你需要index。这也可以用out index。对于你的第二个问题,你可以使用WHEREBETWEEN子句。
参考:http://www.w3schools.com/sql/sql_between.asp

fd3cxomn

fd3cxomn7#

EXPLAIN语句在这种情况下非常有用。对于查询,可以按如下方式使用该语句:

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

这将输出执行查询所使用的索引,并允许您使用不同的索引进行实验以找到最佳配置。为了加快排序,您将需要BTREE索引,因为它以排序的方式存储数据。为了加快查找具有特定ID的项,HASH索引是更好的选择,因为它提供了对相等 predicate 的快速查找。请注意,MySQL可能无法使用两个索引的组合来执行查询,而只使用其中一个。
更多信息:http://dev.mysql.com/doc/refman/5.7/en/using-explain.html
对于范围 predicate ,如日期范围中的日期,BTREE索引的性能优于HASH索引。
更多信息:http://dev.mysql.com/doc/refman/5.7/en/create-index.html

相关问题