Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/64.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_Optimization_Range_Full Text Search - Fatal编程技术网

MySQL:优化记录范围的搜索。

MySQL:优化记录范围的搜索。,mysql,sql,optimization,range,full-text-search,Mysql,Sql,Optimization,Range,Full Text Search,我刚刚在我的应用程序中看到一个非常慢的查询。表“新闻”有超过60万条记录 当我执行: SELECT news.id FROM `news` WHERE (newstime between '2012-01-16 00:00:00' AND '2012-01-16 23:59:59') AND ((MATCH(titolo, testo) AGAINST('"Public Administration" "SOMETHING" "ELSE" "ROMA" "MILANO"' IN BOOLEAN

我刚刚在我的应用程序中看到一个非常慢的查询。表“新闻”有超过60万条记录

当我执行:

SELECT news.id FROM `news` WHERE (newstime between '2012-01-16 00:00:00' AND  '2012-01-16 23:59:59') AND ((MATCH(titolo, testo) AGAINST('"Public Administration" "SOMETHING" "ELSE" "ROMA" "MILANO"' IN BOOLEAN MODE))) ORDER BY newstime DESC LIMIT 23 OFFSET 0;
23 rows in set (26.32 sec)
出于某种原因,MySQL没有执行范围选择,每天只有10000条记录,看起来它在搜索整个表,因为当我从子查询中选择时:

 SELECT id FROM(SELECT * from news where newstime between '2012-01-16 00:00:00' AND  '2012-01-16 23:59:59') as N where ((MATCH(titolo, testo) AGAINST('"Public Administration" "FIAT" "SOMETHING" "ELSE" "ROMA" "MILANO"' IN BOOLEAN MODE))) ORDER BY newstime DESC LIMIT 23 OFFSET 0;

23 rows in set (0.09 sec)
我的查询在0.09秒后返回

26->0.09秒

我认为MySQL将足够智能,可以根据newstime选择记录范围,然后进行全文搜索,但看起来情况并非如此。这正常吗?还是应该尝试优化第一个查询?当我写解释1时,它告诉我:

mysql> explain SELECT news.id FROM `news` WHERE (newstime between '2012-01-16 00:00:00' AND  '2012-01-16 23:59:59') AND ((MATCH(titolo, testo) AGAINST('"Public Administration" "FIAT" "SOMETHING" "ELSE" "ROMA" "MILANO"' IN BOOLEAN MODE))) ORDER BY newstime DESC LIMIT 23 OFFSET 0;
+----+-------------+-------+----------+--------------------------------+---------+---------+------+------+-----------------------------+
| id | select_type | table | type     | possible_keys                  | key     | key_len | ref  | rows | Extra                       |
+----+-------------+-------+----------+--------------------------------+---------+---------+------+------+-----------------------------+
|  1 | SIMPLE      | news  | fulltext | index_news_on_newstime,alltext | alltext | 0       |      |    1 | Using where; Using filesort |
+----+-------------+-------+----------+--------------------------------+---------+---------+------+------+-----------------------------+
为什么使用全文键而不是新闻时间

显示创建表新闻如下所示:

 CREATE TABLE `news` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `titolo` varchar(255) DEFAULT NULL,
  `testo` mediumtext,
  `newstime` datetime NOT NULL,
  `created_at` datetime DEFAULT NULL
  PRIMARY KEY (`id`),
  KEY `index_news_on_newstime` (`newstime`),
  FULLTEXT KEY `alltext` (`titolo`,`testo`)
) ENGINE=MyISAM AUTO_INCREMENT=1846714 DEFAULT CHARSET=utf8 |

为什么呢

为什么?只是MySQL查询优化器并不完美。有时它会选择不太理想的索引。您可以通过告诉MySQL使用哪个索引来纠正这个问题

从文档中: 您还可以使用FORCE INDEX,其作用类似于use INDEX_list,但另外,表扫描被认为是非常昂贵的。换句话说,只有在无法使用给定索引之一查找表中的行时,才使用表扫描

SELECT news.id 
FROM `news` 
USE INDEX (index_news_on_newstime) 
WHERE (newstime between '2012-01-16 00:00:00' AND  '2012-01-16 23:59:59') 
  AND ((MATCH(titolo, testo) AGAINST('"Public Administration" "SOMETHING" "ELSE" "ROMA" "MILANO"' IN BOOLEAN MODE))) 
ORDER BY newstime DESC LIMIT 23 OFFSET 0;
SELECT news.id 
FROM `news` 
FORCE INDEX (index_news_on_newstime) 
WHERE (newstime between '2012-01-16 00:00:00' AND  '2012-01-16 23:59:59') 
  AND ((MATCH(titolo, testo) AGAINST('"Public Administration" "SOMETHING" "ELSE" "ROMA" "MILANO"' IN BOOLEAN MODE))) 
ORDER BY newstime DESC LIMIT 23 OFFSET 0;