【发布时间】:2021-05-08 07:58:37
【问题描述】:
我有一个名为tablename 的表,其结构如下:
CREATE TABLE `tablename` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`user_id` bigint(20) unsigned NOT NULL,
`type` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`data` longtext COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `tablename_user_id_foreign` (`user_id`),
CONSTRAINT `tablename_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=11271577 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
此表的当前大小是4.1Gb,我希望它会变得更大。
我正在运行一个相当简单的 SQL SELECT 查询,如下所示:
SELECT `type`, `data`, `created_at`
FROM `tablename`
WHERE `type` = 'PURCHASE'
ORDER BY `created_at` DESC
LIMIT 1
本质上,我们希望只返回一个(而不是更多)此数据库(PURCHASE 类型)中的最新行。此表中的大多数数据不是PURCHASE 类型。
在具有 4GB RAM 的生产数据库上,可以看到此查询需要长达 1 分 1 秒(这似乎太长了)。
SELECT `type`, `data`, `created_at`
FROM `tablename`
WHERE `type` = 'PURCHASE'
ORDER BY `created_at` DESC
LIMIT 1;
/* Affected rows: 0 Found rows: 1 Warnings: 0 Duration for 1 query: 00:01:01.8 */
在其他运行(相同的机器,相同的服务器)上,我发现它需要在 27 seconds 和 36.48 秒之间。
如果可能的话,我希望最多能缩短几秒钟。
MariaDB 的版本是 10.3.27(在具有 4Gb RAM 和“通用 (SSD) 卷”的 *nix 虚拟云实例上运行)。这是正常的吗?可以做些什么来加快这个查询?瓶颈主要与 RAM 或磁盘速度或其他因素有关吗?
值得注意的是,很多新记录被写入/插入到同一个表中,同时这个SELECT 语句可能正在执行,所以这可能会减慢速度(等待@987654332 @ 语句可能会完成)。
【问题讨论】:
-
想象你是数据库引擎。您会收到这样的查询,并且在您面前有一个无序的表格(想想 Excel 电子表格)。您将如何在其中搜索最新日期?你必须遍历整个表。现在想象一下,您有一个字典样式的索引,首先按
type排序,然后按created_date排序,并且您可以查找每行所在位置的参考。现在很简单,马上去PURCHASE参加第一次约会。 -
很好的解释,很有意义。谢谢。