MySQL:优化记录范围的搜索。
我刚刚在我的应用程序中看到一个非常慢的查询。表“新闻”有超过60万条记录 当我执行: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
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;