为了加快搜索速度,我已经索引了两列(复合索引)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
列用于搜索?
答案 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)
EXPLAIN
与CREATE 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
的两个部分。但该批次中有一百万行用于该客户端,因此查询需要时间。
如果您想讨论如何进一步加快使用此表,请提供其他常见查询。 (我不想调整架构以使此查询更快,只是发现其他查询变得更慢。)