我有几个查询可以使用一些优化,因为它们需要相当长的时间,所以在阅读了这个站点上的许多帖子后,我开始修改我的架构并添加/更改索引以适当地加快查询速度。在大多数情况下,我都取得了巨大的成功,但是在这种特殊情况下,我被卡住了,我不确定自己做错了什么。
我有一张表,里面有大约 350 万行。
select count(*) from post;
+----------+
| count(*) |
+----------+
| 3652904 |
+----------+
并创建如下:
Create Table: CREATE TABLE `post` (
`id` varchar(255) NOT NULL DEFAULT '',
`page_id` bigint(20) NOT NULL DEFAULT '0',
`post_id` bigint(20) NOT NULL DEFAULT '0',
`type` varchar(45) CHARACTER SET latin1 NOT NULL,
...
`created_time` timestamp NULL DEFAULT NULL,
`updated_time` timestamp NULL DEFAULT NULL,
`timestamp` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`page_id`,`post_id`),
KEY `created_time` (`created_time`),
KEY `target_id` (`target_id`),
KEY `id` (`id`) USING BTREE
) ENGINE=TokuDB DEFAULT CHARSET=utf8
/*!50100 PARTITION BY HASH (page_id)
PARTITIONS 10 */
另一个表的行数很少,创建如下:
select count(*) from privacy;
+----------+
| count(*) |
+----------+
| 19093 |
+----------+
Create Table: CREATE TABLE `privacy` (
`id` varchar(255) CHARACTER SET latin1 NOT NULL,
`page_id` bigint(20) DEFAULT '0',
`description` text CHARACTER SET latin1,
`value` varchar(255) CHARACTER SET latin1 DEFAULT NULL,
`allow` varchar(255) CHARACTER SET latin1 DEFAULT NULL,
`deny` varchar(255) CHARACTER SET latin1 DEFAULT NULL,
`json` text CHARACTER SET latin1,
`timestamp` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `page_id` (`page_id`)
) ENGINE=TokuDB DEFAULT CHARSET=utf8
我要优化的选择如下:
explain partitions
SELECT
post.id, post.type, privacy.description
FROM
post
LEFT JOIN privacy ON privacy.id = post.id
WHERE post.page_id = 12854644836;
+----+-------------+---------+------------+------+---------------+---------+---------+-------+-------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+------------+------+---------------+---------+---------+-------+-------+-------+
| 1 | SIMPLE | post | p6 | ref | PRIMARY | PRIMARY | 8 | const | 34685 | |
| 1 | SIMPLE | privacy | NULL | ALL | NULL | NULL | NULL | NULL | 19093 | |
+----+-------------+---------+------------+------+---------------+---------+---------+-------+-------+-------+
不幸的是,这个选择需要几分钟,我不知道为什么。我注意到解释没有选择主键,我想知道这是否是由于两个表之间的字符集不同。即便如此,从解释来看也不应该涉及那么多行,但执行起来仍然需要那么长时间。
16754 rows in set (5 min 33.68 sec)
仅从表格中进行选择就非常快。
select * from post where page_id = 12854644836;
16754 rows in set (0.22 sec)
和
select * from privacy where page_id = 12854644836;
234 rows in set (0.01 sec)
这个网站上的一些 MySQL 大师能否为我指明正确的方向?谢谢 :)