MariaDB社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 3710|回复: 6
打印 上一主题 下一主题

关于数据表索引的使用优化问题

[复制链接]
跳转到指定楼层
1#
发表于 2008-5-4 13:03:02 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
t表中5000条数据,有flag字段,等于1的2500条,等于0的2500条,在flag上建了索引,
当使用查询select * from t where flag=1 limit 10 的时候还是会扫描2000多行,应该怎么做可以使它就扫描10行啊?
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 转播转播 分享分享 分享淘帖 顶 踩
2#
发表于 2008-5-5 09:52:36 | 只看该作者
好问题...
3#
发表于 2008-5-13 17:57:49 | 只看该作者
不知道楼主说的扫描2000多行,是否是指explain中的rows列的值。

如果是的话,我觉得和“等于1的2500条”没有什么直接关系。我作了个例子,如下:
mysql> select count(*) from DEVICEINFO;
+----------+
| count(*) |
+----------+
|     5000 |
+----------+
1 row in set (0.00 sec)
这个表中有5000条记录
-------------------------------------------------------------------------------------
mysql> select count(*) from DEVICEINFO WHERE STATUS=1;
+----------+
| count(*) |
+----------+
|     5000 |
+----------+
1 row in set (0.02 sec)
其中status都是等于1
---------------------------------------------------------------------------------------
mysql> select * from DEVICEINFO WHERE STATUS=1 LIMIT 10;
我执行如下查询仅需要0.01秒
---------------------------------------------------------------------------------------
看一下它的explain
mysql> explain select * from DEVICEINFO WHERE STATUS=1 LIMIT 10;
+----+-------------+------------+------+---------------+--------------+---------+-------+------+-------+
| id | select_type | table      | type | possible_keys | key          | key_len | ref   | rows | Extra |
+----+-------------+------------+------+---------------+--------------+---------+-------+------+-------+
|  1 | SIMPLE      | DEVICEINFO | ref  | status_Index  | status_Index | 2       | const | 2505 |       |
+----+-------------+------------+------+---------------+--------------+---------+-------+------+-------+
1 row in set (0.00 sec)
扫描了2505行,实际上匹配的记录数是5000行。因此说明这只是一个大概的值。而不是真实扫描的记录数。
----------------------------------------------------------------------------------------
mysql> explain select * from DEVICEINFO WHERE STATUS=1 LIMIT 100;
+----+-------------+------------+------+---------------+--------------+---------+-------+------+-------+
| id | select_type | table      | type | possible_keys | key          | key_len | ref   | rows | Extra |
+----+-------------+------------+------+---------------+--------------+---------+-------+------+-------+
|  1 | SIMPLE      | DEVICEINFO | ref  | status_Index  | status_Index | 2       | const | 2505 |       |
+----+-------------+------------+------+---------------+--------------+---------+-------+------+-------+
1 row in set (0.00 sec)
mysql> explain select * from DEVICEINFO WHERE STATUS=1 LIMIT 5000;
+----+-------------+------------+------+---------------+--------------+---------+-------+------+-------+
| id | select_type | table      | type | possible_keys | key          | key_len | ref   | rows | Extra |
+----+-------------+------------+------+---------------+--------------+---------+-------+------+-------+
|  1 | SIMPLE      | DEVICEINFO | ref  | status_Index  | status_Index | 2       | const | 2505 |       |
+----+-------------+------------+------+---------------+--------------+---------+-------+------+-------+
1 row in set (0.00 sec)

我把limit改为100或者5000,同样还是2505,因此进一步证明这个值跟扫描多少记录无关。
---------------------------------------------------------------------------------------------------------------------------
进一步测试,用update语句把其中的2500条记录的status改为0,再测试

mysql> explain select * from DEVICEINFO WHERE STATUS=1 LIMIT 5000;
+----+-------------+------------+------+---------------+--------------+---------+-------+------+-------+
| id | select_type | table      | type | possible_keys | key          | key_len | ref   | rows | Extra |
+----+-------------+------------+------+---------------+--------------+---------+-------+------+-------+
|  1 | SIMPLE      | DEVICEINFO | ref  | status_Index  | status_Index | 2       | const | 2531 |       |
+----+-------------+------------+------+---------------+--------------+---------+-------+------+-------+
1 row in set (0.00 sec)
mysql> explain select * from DEVICEINFO WHERE STATUS=1 LIMIT 10;
+----+-------------+------------+------+---------------+--------------+---------+-------+------+-------+
| id | select_type | table      | type | possible_keys | key          | key_len | ref   | rows | Extra |
+----+-------------+------------+------+---------------+--------------+---------+-------+------+-------+
|  1 | SIMPLE      | DEVICEINFO | ref  | status_Index  | status_Index | 2       | const | 2526 |       |
+----+-------------+------------+------+---------------+--------------+---------+-------+------+-------+
1 row in set (0.01 sec)
mysql> explain select * from DEVICEINFO WHERE STATUS=1 LIMIT 100;
+----+-------------+------------+------+---------------+--------------+---------+-------+------+-------+
| id | select_type | table      | type | possible_keys | key          | key_len | ref   | rows | Extra |
+----+-------------+------------+------+---------------+--------------+---------+-------+------+-------+
|  1 | SIMPLE      | DEVICEINFO | ref  | status_Index  | status_Index | 2       | const | 2526 |       |
+----+-------------+------------+------+---------------+--------------+---------+-------+------+-------+
1 row in set (0.00 sec)
mysql> explain select * from DEVICEINFO WHERE STATUS=1 LIMIT 5000;
+----+-------------+------------+------+---------------+--------------+---------+-------+------+-------+
| id | select_type | table      | type | possible_keys | key          | key_len | ref   | rows | Extra |
+----+-------------+------------+------+---------------+--------------+---------+-------+------+-------+
|  1 | SIMPLE      | DEVICEINFO | ref  | status_Index  | status_Index | 2       | const | 2526 |       |
+----+-------------+------------+------+---------------+--------------+---------+-------+------+-------+
1 row in set (0.00 sec)

可以看到没有什么特定的规律。因此结论:这个rows值与实际扫描记录数无关。


另外像这样的语句,仅需要0.01秒的执行时间,有必要再优化吗?

[ 本帖最后由 edwin_chen 于 2008-5-13 17:59 编辑 ]
4#
发表于 2008-5-27 19:21:29 | 只看该作者
5#
发表于 2008-6-3 10:02:47 | 只看该作者
详细,高见,赞...
6#
发表于 2008-9-1 16:57:25 | 只看该作者
那这个rows有什么用呢,只能通过查询时间来判断使用索引的好处了?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|Archiver|小黑屋|手机版|MariaDB社区 ( 京ICP备07012489号    |
业务联系: QQ:48474881; 邮箱: 48474881@qq.com; 电话:13911732319
声明:本站部分文章是网友转载,若未经作者同意或署名有误,请联系网站管理员。

GMT+8, 2024-11-25 16:31 , Processed in 0.077685 second(s), 20 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表