MySQL添加长文本列使得查询速度非常慢-有性能提示吗?

MySQL添加长文本列使得查询速度非常慢-有性能提示吗?,mysql,sql,sqlperformance,Mysql,Sql,Sqlperformance,我有一张名为stories的表格,目前有1200万条生产记录 CREATE TABLE `stories` ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, `headline` varchar(255) DEFAULT NULL, `author_id` int(11) DEFAULT NULL, `body` longtext NOT NULL, `published_at` datetime DEFAULT NULL

我有一张名为stories的表格,目前有1200万条生产记录

CREATE TABLE `stories` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `headline` varchar(255) DEFAULT NULL,
  `author_id` int(11) DEFAULT NULL,
  `body` longtext NOT NULL,
  `published_at` datetime DEFAULT NULL,
  `type_id` int(11) NOT NULL DEFAULT '0',
  `created_at` datetime DEFAULT NULL,
  `updated_at` datetime DEFAULT NULL,
  `aasm_state` varchar(255) NOT NULL,
  `deleted` tinyint(1) DEFAULT '0',
  `word_count` int(11) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`),
  UNIQUE KEY `index_stories_on_cms_story_id` (`cms_story_id`),
  KEY `typeid` (`type_id`),
  KEY `index_stories_on_published_at` (`published_at`),
  KEY `index_stories_on_updated_at` (`updated_at`),
  KEY `index_stories_on_aasm_state_and_published_at_and_deleted` (`aasm_state`,`published_at`,`deleted`),
  KEY `idx_author_id` (`author_id`)
) ENGINE=InnoDB AUTO_INCREMENT=511625276 DEFAULT CHARSET=utf8;
我正在执行以下查询:仅获取id运行正常

SELECT  `stories`.id 
  FROM `stories` 
 WHERE `stories`.`aasm_state` = 'scheduled'  
   AND `stories`.`deleted` = 0 
   AND (`stories`.`published_at` <= '2020-01-14 06:16:04') 
   AND (`stories`.`id` > 519492608)  
 ORDER 
    BY `stories`.`id` ASC 
  LIMIT 1000;
...
1000 rows in set (0.59 sec)
但是,当我向其中添加长文本列时,我得到:

mysql> SELECT  `stories`.id
, `stories`.body 
FROM `stories` 
WHERE `stories`.`aasm_state` = 'scheduled' 
AND `stories`.`deleted` = 0 
AND (`stories`.`published_at` <= '2020-01-14 06:16:04') 
AND (`stories`.`id` > 519492608)  
ORDER BY `stories`.`id` ASC LIMIT 1000;
...
1000 rows in set (6 min 34.11 sec)

关于如何处理此表的任何性能提示?

通常,关系型DBMS在检索初始结果集后会应用ORDER BY,因此需要加载所有这些故事,然后对它们进行排序。我没有访问您的记录集的权限,但据猜测,在检索批量内容之前应用排序可能会提高性能:

SELECT *
FROM (
   SELECT  `stories`.id 
   FROM `stories` 
   WHERE `stories`.`aasm_state` = 'scheduled'  
   AND `stories`.`deleted` = 0 
   AND (`stories`.`published_at` <= '2020-01-14 06:16:04') 
   AND (`stories`.`id` > 519492608)  
   ORDER BY `stories`.`id` ASC 
   LIMIT 1000
) ids 
INNER JOIN stories bulk
ON ids.id=bulk.id

BTW,你可以考虑更多的研究索引——你所说的看起来很可疑。

< P>典型的关系DBMS将在检索初始结果集之后应用ORDER——因此需要加载所有这些故事然后排序它们。我没有访问您的记录集的权限,但据猜测,在检索批量内容之前应用排序可能会提高性能:

SELECT *
FROM (
   SELECT  `stories`.id 
   FROM `stories` 
   WHERE `stories`.`aasm_state` = 'scheduled'  
   AND `stories`.`deleted` = 0 
   AND (`stories`.`published_at` <= '2020-01-14 06:16:04') 
   AND (`stories`.`id` > 519492608)  
   ORDER BY `stories`.`id` ASC 
   LIMIT 1000
) ids 
INNER JOIN stories bulk
ON ids.id=bulk.id

BTW,你可以考虑更多地研究索引——你所说的看起来很可疑。

< P>我推荐索引的顺序:

INDEX(`aasm_state`,`deleted`,id)
把=测试放在第一位 以与ORDER BY匹配的范围结束;希望这样可以避免收集大量的行,并在达到限制之前对它们进行排序。
此索引可能有助于查询的所有变体。

我建议索引的顺序如下:

INDEX(`aasm_state`,`deleted`,id)
把=测试放在第一位 以与ORDER BY匹配的范围结束;希望这样可以避免收集大量的行,并在达到限制之前对它们进行排序。
此索引可能有助于查询的所有变体。

您能用解释结果更新您的问题吗?另外,您使用的是MyISAM还是InnoDB?InnoDB@JaredDunham@JaredDunhamexplain的specfic中的任何列都会有用吗?选择类型,类型,可能的键,键,键长度,行,过滤的,额外的长文本列的平均大小是多少?如果每条记录都有1GB的数据,那么6分钟内大约1TB的数据就没那么糟糕了……您能用解释结果更新您的问题吗?另外,您使用的是MyISAM还是InnoDB?InnoDB@JaredDunham@JaredDunhamexplain的specfic中的任何列都会有用吗?选择类型,类型,可能的键,键,键长度,行,过滤的,额外的长文本列的平均大小是多少?如果每条记录都有1GB的数据,那么6分钟内大约1TB的数据就没那么糟糕了……谢谢@symcbean,肯定会的,非常简单的建议,帮助很大!谢谢@symcbean,一定会的,很好很简单的建议,帮助很大!