【发布时间】:2022-01-09 08:50:51
【问题描述】:
上下文
我有一张大桌子,里面装满了由外部来源更新的“文档”。当我注意到更新比我上一个接触点更新时,我需要处理这些文档。不过我遇到了一些严重的性能问题。
示例代码
select count(*) from documents;
在 1 分 15.24 秒内返回 212,494,397 个文档。
select count(*) from documents where COALESCE( updated_at > last_indexed_at, TRUE);
实际查询在 14 分 36.23 秒内获得了 55,988,860 个。
select count(*) from documents where COALESCE( updated_at > last_indexed_at, TRUE) limit 1;
同样需要大约 15 分钟。 (这让我很惊讶)
问题
如何执行
updated_at > last_indexed_at更多 合理的时间?
详情
我很确定我的查询在某种程度上是不可搜索的。不幸的是,我找不到这个查询阻止它在行独立的基础上执行的原因。
select count(*)
from documents
where last_indexed_at is null or updated_at > last_indexed_at;
并没有做得更好。
也没有
select count( distinct( id ) )
from documents
where last_indexed_at is null or updated_at > last_indexed_at limit 1;
也没有
select count( distinct( id ) )
from documents limit 1;
编辑:跟进请求的数据
这个问题只涉及rails项目中的一个表(谢天谢地),所以我们很方便地为表定义了rails。
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `documents` (
`id` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`document_id` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`document_type` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`locale` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`allowed_ids` text COLLATE utf8mb4_unicode_ci NOT NULL,
`fields` mediumtext COLLATE utf8mb4_unicode_ci,
`created_at` datetime(6) NOT NULL,
`updated_at` datetime(6) NOT NULL,
`last_indexed_at` datetime(6) DEFAULT NULL,
`deleted_at` datetime(6) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `index_documents_on_document_type` (`document_type`),
KEY `index_documents_on_locale` (`locale`),
KEY `index_documents_on_last_indexed_at` (`last_indexed_at`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
SELECT VERSION(); 找我5.7.27-30-log
而且可能是最重要的,
explain select count(*) from documents where COALESCE( updated_at > last_indexed_at, TRUE);
完全了解我
+----+-------------+-----------+------------+------+---------------+------+---------+------+-----------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-----------+------------+------+---------------+------+---------+------+-----------+----------+-------------+
| 1 | SIMPLE | documents | NULL | ALL | NULL | NULL | NULL | NULL | 208793754 | 100.00 | Using where |
+----+-------------+-----------+------------+------+---------------+------+---------+------+-----------+----------+-------------+
【问题讨论】:
-
explain select count(*) from documents;显示什么?实际上每个解释说明了什么?在问题中也发布show create table documents。 -
你可以运行
EXPLAIN select count(*) from documents USE INDEX (PRIMARY)看看会发生什么 -
还有什么我可以补充的吗?
标签: mysql sql optimization query-optimization