我的数据库存储在Google Cloud SQL(MySQL(中。该表有大约 11M 行。 为什么简单选择计数这么慢?
我正在使用以下查询:
select count(*) from my_table;
响应时间例如:
- 超过 2 分钟
- 29秒
- 3s(是否使用了某些缓存?
数据库没有一些简单的行计数计数器吗?我想计数查询应该立即计算。
我可以加快速度吗?
注1:我会说一个月前它工作正常,但我不确定。
注 2:表大小为 4GB,计算机为 db-n1-standard-2(2vCPU,7.5 GB(
更新 8月 14
COUNT今天很快。最糟糕的时间是4s。明天的滞后是由谷歌平台的一些问题引起的吗?我可以直接通过ssh连接到SQL机器来监视其资源和交换文件吗?
我尝试了汤米的暗示,还有另一件奇怪的事情。"说明"显示许多表列的 NULL。可能是由不同的服务器版本引起的吗?我的Server version: 5.7.14-google-log (Google)
我使用过:
explain select count(1) from my_table;
结果是:
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
| 1 | SIMPLE | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | Select tables optimized away |
在 JSON 中:
{
"query_block": {
"select_id": 1,
"message": "Select tables optimized away"
}
默认情况下,数据库通常针对特定类型的使用模式进行优化。因此,做任何额外的工作都会对性能产生不必要的负面影响。即使保持简单的计数也没有完成,因为它可以对每秒可以做多少事情产生严重的影响。
这是一个你可以尝试的实验(MySQL 5.7(。首先创建一个没有索引的简单表。
create table A (
B int
);
explain select count(1) from A;
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 SIMPLE A NULL ALL NULL NULL NULL NULL 1 100.00 NULL
作为 json:
{
"data":
[
{
"id": 1,
"select_type": "SIMPLE",
"table": "A",
"partitions": null,
"type": "ALL",
"possible_keys": null,
"key": null,
"key_len": null,
"ref": null,
"rows": 1,
"filtered": 100,
"Extra": null
}
]
}
Explain
输出的重要部分是"type": "ALL"
部分,它表示要获得调用,数据库必须检索所有行,即表扫描。这就是选择计数缓慢的原因。
您可以通过在表上创建索引来告诉数据库计数对您很重要。每次插入后,数据库都必须更新该表的索引。
因此,让我们添加一个索引:alter table A add index idx_A(B);
。并重新运行explain
语句:
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
1 SIMPLE A NULL index NULL idx_A 5 NULL 1 100.00 Using index
再次采用 json 格式:
{
"data":
[
{
"id": 1,
"select_type": "SIMPLE",
"table": "A",
"partitions": null,
"type": "index",
"possible_keys": null,
"key": "idx_A",
"key_len": "5",
"ref": null,
"rows": 1,
"filtered": 100,
"Extra": "Using index"
}
]
}
这一次,请注意type
,它是index
的,并且有一个可以使用的密钥。该索引将允许查询计算器更快地返回计数。