我有一个很大的表(大约30 M行),它通常运行得很快(每个请求5- 6 ms)。有时一个请求需要很多时间(大约60秒)。
这里的表结构:
CREATE TABLE table (
id int(11) NOT NULL,
A int(11) NOT NULL,
B varchar(32) NOT NULL,
C tinyint(1) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
ALTER TABLE `table`
ADD PRIMARY KEY (id),
ADD KEY A (A),
ADD KEY B (B);
字符串
索引A的基数为2 M,索引B的基数为1 k。
我的请求是:
SELECT * FROM table
WHERE A = someAvalue
AND B = 'some B value'
AND C = 0
ORDER BY id DESC
LIMIT 1;
型
并对结果进行了解释:
id|select_type|table|type|possible_keys|key|key_len|ref |rows|Extra
1 |SIMPLE |table|ref |A,B |B |34 |const|1 |Using index condition; Using where; Using filesort
型key_len
和rows
与本例无关,因为它来自一个重复查询
如果我删除AND C = 0
请求运行一个正常的时间量。似乎这个请求去野生时,索引A和B返回无值。
所以这里我的问题是:为什么在这种情况下添加一个非索引字段可以使请求在60秒以上而不是几毫秒内运行?
3条答案
按热度按时间9bfwbjaz1#
有几个潜在的原因可以解释这种行为:
f8rj6qna2#
为什么我选择索引字段和非索引字段有时需要很长时间?
第一个重要的问题是MyISAM存储引擎的使用,请切换到InnoDB。MyISAM只支持表锁,即使是select语句。
参见What are the main differences between InnoDB and MyISAM?
然后在你的表上添加以下索引。
字符串
erhoui1w3#
Ekans,策略性放置的括号使用应避免C = 0的表扫描。
SELECT * FROM my_table WHERE(A = someAvalue AND B = 'some B value')AND C = 0 ORDER BY id DESC LIMIT 1;
请验证您的MySQL版本,并让我们知道这个解决方案需要多长时间。
并张贴解释请比较。