一张ip表,数据量35w条左右,select ip_id, ip_start, ip_end, ip_country, ip_local, ip_province_code, ip_city_code from t_ip_address where ip_start <=3663609113 and ip_end >=3663609113#创建3个索引
create index index_start_end on t_ip_address(ip_start,ip_end)create index index_start on t_ip_address(ip_start)create index index_end on t_ip_address(ip_end)#FORCE INDEX分别使用索引EXPLAIN select * from t_ip_address FORCE INDEX(index_start_end) where ip_start <=1663609113 and ip_end >=1663609113*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: t_ip_address
         type: ALL
possible_keys: i_start_end
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 100993
        Extra: Using where
1 row in set (0.00 sec)其他情况FORCE INDEX(index_start) 或者 FORCE INDEX(index_end)  显示同上type:all,key:null,是什么原因没用使用索引查询???
看了mysqlperformanceblog里面例子是没有问题的,为什么这张表没有效果?还请帮忙,!!!ps:本人结贴很到位,学习是目的

解决方案 »

  1.   

    看一下 show index from t_ip_address; 的结果。
      

  2.   

    为了加快测试速度,我删除了一些数据,保留10w条
    delete from  t_ip_address where ip_id>100000
    按照1楼的知识,显示如下:mysql> show index from t_ip_address;
    +--------------+------------+-----------------+--------------+-------------+----
    -------+-------------+----------+--------+------+------------+---------+
    | Table        | Non_unique | Key_name        | Seq_in_index | Column_name | Col
    lation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
    +--------------+------------+-----------------+--------------+-------------+----
    -------+-------------+----------+--------+------+------------+---------+
    | t_ip_address |          0 | PRIMARY         |            1 | ip_id       | A
           |       98638 |     NULL | NULL   |      | BTREE      |         |
    | t_ip_address |          1 | index_start     |            1 | ip_start    | A
           |       98638 |     NULL | NULL   | YES  | BTREE      |         |
    | t_ip_address |          1 | index_end       |            1 | ip_end      | A
           |       98638 |     NULL | NULL   | YES  | BTREE      |         |
    | t_ip_address |          1 | index_start_end |            1 | ip_start    | A
           |       98638 |     NULL | NULL   | YES  | BTREE      |         |
    | t_ip_address |          1 | index_start_end |            2 | ip_end      | A
           |       98638 |     NULL | NULL   | YES  | BTREE      |         |
    +--------------+------------+-----------------+--------------+-------------+----
    -------+-------------+----------+--------+------+------------+---------+
    5 rows in set (0.14 sec)显示有点乱
      

  3.   

    从你的索引信息看很有趣, 
    你的几个字段在表中基本上都没有重复的。mysql> show index from t_ip_address;
    +--------------+------------+-----------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
    | Table        | Non_unique | Key_name        | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
    +--------------+------------+-----------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
    | t_ip_address |          0 | PRIMARY         |            1 | ip_id       | A         |       98638 |     NULL | NULL   |      | BTREE      |         |
    | t_ip_address |          1 | index_start     |            1 | ip_start    | A         |       98638 |     NULL | NULL   | YES  | BTREE      |         |
    | t_ip_address |          1 | index_end       |            1 | ip_end      | A         |       98638 |     NULL | NULL   | YES  | BTREE      |         |
    | t_ip_address |          1 | index_start_end |            1 | ip_start    | A         |       98638 |     NULL | NULL   | YES  | BTREE      |         |
    | t_ip_address |          1 | index_start_end |            2 | ip_end      | A         |       98638 |     NULL | NULL   | YES  | BTREE      |         |
    +--------------+------------+-----------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
    5 rows in set (0.14 sec)
    建议先用 analyze table t_ip_address; 让索引信息重新刷新一下。
    再 show index from t_ip_address; 一下。然后
    select count(*) from t_ip_address; 
    select count(*) from t_ip_address where ip_start <=1663609113 ;
    select count(*) from t_ip_address where ip_end >=1663609113;在count(*)的结果几乎=表中总记录数的时候,mysql会使用全表扫描而不是去利用索引。
      

  4.   

    谢你的回复,昨晚琢磨了很久,后来注意到一个事情,就是mysqlperformanceblog里面例子的是int类型的,我用的是字符串varchar,change类型到int(长度10,刚好)就能用索引了。速度提升明显:  1.5秒左右-0.1秒左右