Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
慢速MySQL按日期时间列排序_Mysql_Sql_Innodb - Fatal编程技术网

慢速MySQL按日期时间列排序

慢速MySQL按日期时间列排序,mysql,sql,innodb,Mysql,Sql,Innodb,我有如下定义的新闻表: CREATE TABLE `news` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `creation_date` datetime DEFAULT NULL, `modification_date` datetime DEFAULT NULL, `active` bit(1) DEFAULT NULL, `mark_for_delete` bit(1) DEFAULT NULL, `verified` b

我有如下定义的新闻表:

CREATE TABLE `news` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `creation_date` datetime DEFAULT NULL,
  `modification_date` datetime DEFAULT NULL,
  `active` bit(1) DEFAULT NULL,
  `mark_for_delete` bit(1) DEFAULT NULL,
  `verified` bit(1) DEFAULT NULL,
  `bot_id` int(11) DEFAULT NULL,
  `description` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
  `hash` varchar(100) NOT NULL,
  `published_at` datetime DEFAULT NULL,
  `source` varchar(255) DEFAULT NULL,
  `title` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
  `url` varchar(511) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `UK_1dmji5m90xaiy84vttgkvsub2` (`hash`),
  KEY `index_news_source` (`source`),
  KEY `index_news_creation_date` (`creation_date`)
) ENGINE=InnoDB AUTO_INCREMENT=30887718 DEFAULT CHARSET=latin1
以及用于标记属于某些流行名称的新闻的联接表:

CREATE TABLE `star_news` (
  `stars_id` bigint(20) NOT NULL,
  `news_id` bigint(20) NOT NULL,
  PRIMARY KEY (`stars_id`,`news_id`),
  KEY `FK4eqjn8at6h4d9335q1plxkcnl` (`news_id`),
  CONSTRAINT `FK1olc51y8amp8op1kbmx269bac` FOREIGN KEY (`stars_id`) REFERENCES `star` (`id`),
  CONSTRAINT `FK4eqjn8at6h4d9335q1plxkcnl` FOREIGN KEY (`news_id`) REFERENCES `news` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
下面是我的查询,返回最新消息

SELECT DISTINCT n.* 
FROM news n 
JOIN star_news sn 
  ON n.id = sn.news_id 
WHERE sn.stars_id IN (1234, 12345) 
ORDER BY n.creation_date DESC 
LIMIT 2;
说明:

+----+-------------+-------+------------+--------+-------------------------------------+---------+---------+-----------------------+------+----------+-----------------------------------------------------------+
| id | select_type | table | partitions | type   | possible_keys                       | key     | key_len | ref                   | rows | filtered | Extra                                                     |
+----+-------------+-------+------------+--------+-------------------------------------+---------+---------+-----------------------+------+----------+-----------------------------------------------------------+
|  1 | SIMPLE      | sn    | NULL       | range  | PRIMARY,FK4eqjn8at6h4d9335q1plxkcnl | PRIMARY | 8       | NULL                  |196225|   100.00 | Using where; Using index; Using temporary; Using filesort |
|  1 | SIMPLE      | n     | NULL       | eq_ref | PRIMARY                             | PRIMARY | 8       | cosmos_dev.sn.news_id |    1 |   100.00 | NULL                                                      |
+----+-------------+-------+------------+--------+-------------------------------------+---------+---------+-----------------------+------+----------+-----------------------------------------------------------+
在我的机器上执行此查询需要20秒。如果我删除ORDERBY子句,它将在亚毫秒内返回。如何通过加快运行速度来完成订单


我尝试在创建日使用force index,因为它是一个索引列,但它恶化了性能

所以你有196k篇关于这两颗星的新闻文章?“额外解释”会告诉您发生了什么:

在何处使用;使用指数;使用临时设备;使用文件排序


MySQL正在创建一个临时文件并对其进行排序,以满足order by的要求,因为它无法使用索引来方便按日期加入和排序文章。

那么您有196k篇与这两颗星相关的新闻文章?“额外解释”会告诉您发生了什么:

在何处使用;使用指数;使用临时设备;使用文件排序


MySQL正在创建一个临时文件并对其进行排序,以满足order by的要求,因为它无法使用索引来方便按日期加入和排序文章。

首先,将查询编写为:

SELECT n.* 
FROM news n 
WHERE EXISTS (SELECT 1
              FROM star_news sn 
              WHERE n.id = sn.news_id AND
                    sn.stars_id IN (1234, 12345) 
             )
ORDER BY n.creation_date DESC
LIMIT 2 ;
这样就消除了外部
选择DISTINCT
,这应该会有所帮助


然后,在
star\u news(news\u id,stars\u id)
上创建索引。这还可以利用
新闻(creation\u date desc,id)
上的索引。首先,将查询编写为:

SELECT n.* 
FROM news n 
WHERE EXISTS (SELECT 1
              FROM star_news sn 
              WHERE n.id = sn.news_id AND
                    sn.stars_id IN (1234, 12345) 
             )
ORDER BY n.creation_date DESC
LIMIT 2 ;
这样就消除了外部
选择DISTINCT
,这应该会有所帮助



然后,在
star\u news(news\u id,stars\u id)
上创建索引。这还可以利用
news(creation\u date desc,id)

上的索引问:根据您将运行的正常查询类型,在这种情况下,您对两个stars\u id值(1234,12345)进行查询,如果您没有通过creation\u date descending应用限制2,那么将返回多少行总数。~196k(来自解释结果)我认为不可能找到一个简单的“添加此索引”解决方案。这样的索引不存在,因为您使用一个索引读取记录,并且需要按其他表中的其他字段对结果进行排序。@akuzminsky我想我可以向star_news添加一个名为news_date的新列,并在(news_id,news_date)上创建一个索引。您需要使用相同的索引进行读取和排序。那就快了。因此,它必须是sn表中的(stars_id,news_date)。Q:根据您将运行的正常查询类型,在这种情况下,您将对2个stars_id值(123412345)执行查询,如果不通过创建日期降序应用限制2,将返回多少行。~196k(从解释结果中)我认为不可能找到一个简单的方法“添加此索引”解决方案。此类索引不存在,因为您使用一个索引读取记录,并且需要按其他表中的其他字段对结果进行排序。@akuzminsky我想我可以向star_news添加一个名为news_date的新列,并在(news_id,news_date)上创建索引。您需要使用相同的索引进行读取和排序。这样会很快。因此,它必须是sn表中的(stars\u id,news\u date)。添加了comp索引。相同的解释计划,对新索引强制索引也没有帮助。。这不会有帮助。查询从一个表(sn)中按字段读取记录,并从另一个表(n)中按字段排序。添加了comp索引。相同的解释计划,对新索引强制索引也没有帮助。。那没有帮助。查询从一个表(sn)中按字段读取记录,并从另一个表(n)中按字段排序。但这会变成一个依赖子查询,除非最近写了两篇关于1234或12345的文章。@AndreasWederbrand…不一定。相关子查询通常是查询的最快实现。我一点也不知道为什么这么多人不理解。如果优化器选择扫描
n
by
creation\u date
,它可能在检查30887718行时被卡住。但这会变成一个依赖子查询,除非新写了两篇关于1234或12345的文章。@AndreasWederbrand…不一定。相关子查询通常是查询的最快实现。我不喜欢测试为什么这么多人不理解这一点。如果优化器选择按
creation\u date
扫描
n
,它可能无法检查30887718行。