Mysql查询不使用所有索引列进行搜索

时间:2016-01-02 11:52:25

标签: mysql indexing

为了加快搜索速度,我已经索引了两列(复合索引)client_id和batch_id。

下面是我表格的索引输出

{"status":1,"msg":"","progress":"0.15","time":"<span class=\"text-white\">11:11<\/span> left (at 10KB\/sec)","size":"<span class=\"text-white\">16KB<\/span> \/ 10.91MB (0.15%)"}

当我使用explain检查是否在查询中使用了索引时,它会给出低于输出的结果。

show indexes from authentication_codes

*************************** 3. row ***************************
        Table: authentication_codes
   Non_unique: 1
     Key_name: client_id
 Seq_in_index: 1
  Column_name: client_id
    Collation: A
  Cardinality: 18
     Sub_part: NULL
       Packed: NULL
         Null: YES
   Index_type: BTREE
      Comment:
Index_comment:
*************************** 4. row ***************************
        Table: authentication_codes
   Non_unique: 1
     Key_name: client_id
 Seq_in_index: 2
  Column_name: batch_id
    Collation: A
  Cardinality: 18
     Sub_part: NULL
       Packed: NULL
         Null: YES
   Index_type: BTREE
      Comment:
Index_comment:
4 rows in set (0.02 sec)

ERROR:
No query specified

******************** EDIT ************************** *

show create table authentication_codes的输出如下

mysql> explain select * from authentication_codes where client_id=6 and batch_id="101" \G;


*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: authentication_codes
         type: ref
possible_keys: client_id
          key: client_id
      key_len: 773
          ref: const,const
         rows: 1044778
        Extra: Using where
1 row in set (0.00 sec)

ERROR:
No query specified

我的问题是为什么mysql> show create table authentication_codes \G; *************************** 1. row *************************** Table: authentication_codes Create Table: CREATE TABLE `authentication_codes` ( `id` int(11) NOT NULL AUTO_INCREMENT, `code` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL, `batch_id` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL, `serial_num` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL, `client_id` int(11) DEFAULT NULL, `created_at` datetime DEFAULT NULL, `updated_at` datetime DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `index_authentication_codes_on_code` (`code`), KEY `client_id_batch_id` (`client_id`,`batch_id`) ) ENGINE=InnoDB AUTO_INCREMENT=48406205 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci 1 row in set (0.00 sec) 列不用于搜索。为什么只有batch_id列用于搜索?

2 个答案:

答案 0 :(得分:1)

要在两列上使用索引,您需要创建两列索引。 MySQL不能在一个表上使用两个单独的索引。

此查询将在client_id和batch_id

上添加多列索引
alter table authentication_codes add index client_id_batch_id (client_id,batch_id)

http://dev.mysql.com/doc/refman/5.7/en/multiple-column-indexes.html

答案 1 :(得分:0)

EXPLAINCREATE TABLE不匹配,至少在相关索引的名称中。

解释EXPLAIN(目前显示):

  select_type: SIMPLE
        table: authentication_codes
         type: ref
possible_keys: client_id
          key: client_id    -- The index named "client_id" was used
      key_len: 773          -- (explained below)
          ref: const,const  -- 2 constants were used for the first two columns in that index
         rows: 1044778      -- About this many rows (2% of table) matches those two constants
        Extra: Using where

773 = 2 + 3 * 255 + 1 + 4 + 1
2 = VARCHAR的长度
3 = utf8字符的最大宽度 - 你真的需要utf8吗?
255 = VARCHAR(255)中提供的最大长度 - 你真的需要那么多吗? 1 = NULL的额外长度 - 也许您的列可能/应该是NOT NULL? 4 = INT的{​​{1}}长度 - 如果您不需要40亿个ID,那么可能会使用较小的client_id吗?也许INT也是?

所以,是的,它正在使用UNSIGNED的两个部分。但该批次中有一百万行用于该客户端,因此查询需要时间。

如果您想讨论如何进一步加快使用此表,请提供其他常见查询。 (我不想调整架构以使查询更快,只是发现其他查询变得更慢。)