请教大家一个关于mysql问题:
   我创建了一个测试表:
   CREATE TABLE `a` (
     `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
     `sex` tinyint(4) DEFAULT '0',
     `name` varchar(20) DEFAULT NULL,
     `birthday` datetime DEFAULT NULL,
     PRIMARY KEY (`id`),
     KEY `idx_name` (`name`)
   ) ENGINE=InnoDB AUTO_INCREMENT=100001 DEFAULT CHARSET=utf8
    
   然后,使用索引覆盖查询:
   mysql> explain select id from a where name = '123';
   +----+-------------+-------+------+---------------+----------+---------+-------+------+--------------------------+
   | id | select_type | table | type | possible_keys | key      | key_len | ref   | rows | Extra                    |
   +----+-------------+-------+------+---------------+----------+---------+-------+------+--------------------------+
   |  1 | SIMPLE      | a     | ref  | idx_name      | idx_name | 63      | const |    1 | Using where; Using index |
   +----+-------------+-------+------+---------------+----------+---------+-------+------+--------------------------+
   1 row in set (0.00 sec)
    
   Using Where不就表示mysql服务器接收到存储引擎的数据,然后在服务器端进行过滤吗?为何在此sql中也会出现Using Where ? 我觉得存储引擎可以直接查找到满足条件的数据,并不需要在服务器端进行过滤后再返回给客户端。
在线等,如果问题解决,马上给分!谢谢 ! 

解决方案 »

  1.   

    手册中关键Using where 的解释如下。 你的这个 `idx_name` 并不是唯一键。没有理由不出现 Using where 啊。
      

  2.   

    因为你取得是id,如果select name则不用useing where
      

  3.   

    mysql  help:
    Using whereWHERE子句用于限制哪一个行匹配下一个表或发送到客户。除非你专门从表中索取或检查所有行,如果Extra值不为Using where并且表联接类型为ALL或index,查询可能会有一些错误。 如果想要使查询尽可能快,应找出Using filesort 和Using temporary的Extra值。应该是正常的
      

  4.   

    CHM的解释是对的,LZ理解上有偏差推荐:
    淘宝和阿里巴巴去Oracle化事件 引发数据库技术人员大讨论WebGame行业案例:in子查询group by引发的“血案”
      

  5.   


    mysql> explain select name from a where name = '123';
    +----+-------------+-------+------+---------------+----------+---------+-------+------+--------------------------+
    | id | select_type | table | type | possible_keys | key      | key_len | ref   | rows | Extra                    |
    +----+-------------+-------+------+---------------+----------+---------+-------+------+--------------------------+
    |  1 | SIMPLE      | a     | ref  | idx_name      | idx_name | 63      | const |    1 | Using where; Using index |
    +----+-------------+-------+------+---------------+----------+---------+-------+------+--------------------------+
    1 row in set (0.00 sec)也会出现Using Where的。
      

  6.   

    首先谢谢你,不过我还是那个问题:
    Using Where不就表示mysql服务器接收到存储引擎的数据,然后在服务器端进行过滤吗? 我觉得存储引擎可以直接查找到满足条件的数据,并不需要在服务器端进行过滤后再返回给客户端。正如我那条sql,通过普通索引idx_name将满足条件的id集合返回给服务器端,此时已经是满足条件的集合,为何还要在服务器端进行过滤呢?请赐教!
      

  7.   

    这句话不是来源于MYSQL的说明。 楼主可以详细描述一下这个步骤吗? 可以使用例子来说明一下。这样可以看到哪一个环节上需要更一步讨论。比如 MYSQL 执行这个 where name = '123' 会判断可以使用`idx_name` (`name`),
    MYSQL调用innodb存储引擎去访问`idx_name` (`name`) 索引数据,在访问索引数据时自然要使用 where 方法。
      

  8.   

    在《高性能mysql》中提到:
    Using Where这意味着MySql服务器将在存储引擎收到行后进行过滤。所以我一直认为,当在extra列中出现了Using Where后就表明,mysql服务器在接收到存储引擎的数据后,在服务器端进行了过滤操作,不知道我这话是否正确?谢谢!
      

  9.   

    对应的英文全文:
    “Using where”
    This means the MySQL server will post-filter rows after the storage engine
    retrieves them. Many WHERE conditions that involve columns in an index can be
    checked by the storage engine when (and if) it reads the index, so not all queries
    with a WHERE clause will show “Using where.” Sometimes the presence of “Using
    where” is a hint that the query can benefit from different indexing.
      

  10.   

    刚试了下,当索引字段是char类型,会出现using where,但如果索引是unique,则不出现using where,当字段为数字类型,普通索引也不会出现using where,很奇怪
      

  11.   

    不会吧?我也试了下,如果为数字,也会出现using where的。
      

  12.   

    我的想法是,即使是非唯一索引,也可以在储存引擎这一层将期望的数据过滤出来,并不需要在服务层进一步过滤。
    现在的问题就是using where到底代表什么含义,难道在储存引擎这一层过滤数据也要显示using where?
      

  13.   

    在ID、NAME上建立唯一索引,再EXPLAIN试试
    应该没有WHERE 了
    ALTER TABLE tt ADD UNIQUE `id1` (`id`, `name`); 
      

  14.   

    mysql> show index from a;
    +-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
    | Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
    +-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
    | a     |          0 | PRIMARY  |            1 | id          | A         |      100982 |     NULL | NULL   |      | BTREE      |         |
    | a     |          1 | idx_name |            1 | id          | A         |      100982 |     NULL | NULL   |      | BTREE      |         |
    | a     |          1 | idx_name |            2 | name        | A         |      100982 |     NULL | NULL   | YES  | BTREE      |         |
    +-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
    3 rows in set (0.00 sec)mysql> explain select id from a where name = '123';
    +----+-------------+-------+-------+---------------+----------+---------+------+--------+--------------------------+
    | id | select_type | table | type  | possible_keys | key      | key_len | ref  | rows   | Extra                    |
    +----+-------------+-------+-------+---------------+----------+---------+------+--------+--------------------------+
    |  1 | SIMPLE      | a     | index | NULL          | idx_name | 67      | NULL | 100982 | Using where; Using index |
    +----+-------------+-------+-------+---------------+----------+---------+------+--------+--------------------------+
    1 row in set (0.00 sec)还有有Using Where.
      

  15.   

    楼主是不是有个误区,using where 表示在存储引擎端进行过滤,而不是服务器端过滤。