数据库
首页 > 数据库> > 使用filesort,MYSQL性能变慢

使用filesort,MYSQL性能变慢

作者:互联网

我有一个简单的mysql查询,但是当我有很多记录(目前为103,0000)时,性能非常慢并且它说它正在使用filesort,我不确定这是否是为什么它很慢.有没有人建议加快它?或者使用filesort停止它?

MYSQL查询:

SELECT adverts .*    
FROM adverts
WHERE (
price >='0'
)
AND (
adverts.status = 1
)
AND (
adverts.approved = 1
)
ORDER BY date_updated DESC 
LIMIT 19990 , 10

解释结果:

id   select_type   table   type    possible_keys    key    key_len    ref    rows   Extra 
1    SIMPLE        adverts range   price            price  4          NULL   103854 Using where; Using filesort

这是广告表和索引:

CREATE TABLE `adverts` (
  `advert_id` int(10) NOT NULL AUTO_INCREMENT,
  `user_id` int(10) NOT NULL,
  `type_id` tinyint(1) NOT NULL,
  `breed_id` int(10) NOT NULL,
  `advert_type` tinyint(1) NOT NULL,
  `headline` varchar(50) NOT NULL,
  `description` text NOT NULL,
  `price` int(4) NOT NULL,
  `postcode` varchar(7) NOT NULL,
  `town` varchar(60) NOT NULL,
  `county` varchar(60) NOT NULL,
  `latitude` float NOT NULL,
  `longitude` float NOT NULL,
  `telephone1` varchar(15) NOT NULL,
  `telephone2` varchar(15) NOT NULL,
  `email` varchar(80) NOT NULL,
  `status` tinyint(1) NOT NULL DEFAULT '0',
  `approved` tinyint(1) NOT NULL DEFAULT '0',
  `date_created` datetime NOT NULL,
  `date_updated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `expiry_date` datetime NOT NULL,
  PRIMARY KEY (`advert_id`),
  KEY `price` (`price`),
  KEY `user` (`user_id`),
  KEY `type_breed` (`type_id`,`breed_id`),
  KEY `headline_keywords` (`headline`),
  KEY `date_updated` (`date_updated`),
  KEY `type_status_approved` (`advert_type`,`status`,`approved`)
) ENGINE=MyISAM AUTO_INCREMENT=103878 DEFAULT CHARSET=utf8

解决方法:

问题是MySQL在执行查询时只使用一个索引.如果添加一个使用WHERE子句中的3个字段的新索引,它将更快地找到行.

ALTER TABLE `adverts` ADD INDEX price_status_approved(`price`, `status`, `approved`);

根据MySQL文档ORDER BY Optimization

In some cases, MySQL cannot use indexes to resolve the ORDER BY, although it still uses indexes to find the rows that match the WHERE clause. These cases include the following:
The key used to fetch the rows is not the same as the one used in the ORDER BY.

这就是你的情况.
正如EXPLAIN的输出告诉我们的那样,优化器使用关键价格来查找行.但是,ORDER BY位于字段date_updated上,该字段不属于关键价格.

要更快地查找行并更快地对行进行排序,您需要添加一个索引,该索引包含WHERE和ORDER BY子句中使用的所有字段:

ALTER TABLE `adverts` ADD INDEX status_approved_date_updated(`status`, `approved`, `date_updated`);

用于排序的字段必须位于索引的最后位置.在索引中包含price是没用的,因为查询中使用的条件将返回一系列值.

如果EXPLAIN仍显示它正在使用filesort,您可以尝试强制MySQL使用您选择的索引:

SELECT adverts.*
FROM adverts
FORCE INDEX(status_approved_date_updated)
WHERE price >= 0
AND adverts.status = 1
AND adverts.approved = 1
ORDER BY date_updated DESC 
LIMIT 19990, 10

通常没有必要强制索引,因为MySQL优化器通常做出正确的选择.但有时它会做出错误的选择,或者不是最好的选择.您将需要运行一些测试以查看它是否提高了性能.

标签:performance,mysql,database-performance,filesort
来源: https://codeday.me/bug/20190930/1836152.html