mic*_*ber 12 mysql performance query-performance
对于以下 SELECT 查询,是否可以避免“使用临时”和“使用文件排序”?我想不出办法做到这一点。

我尝试为 top_expire 和 program 添加索引,但没有帮助 ORDER BY 查询需要 1 秒以上,而没有它在 localhost 上仅为 0.003 秒

SELECT ad.*, p.link
FROM (SELECT ad.*
FROM mod_ad ad
JOIN mod_ad_auta auta ON ad.id = auta.ad_id
WHERE ad.active != 0 AND ad.usr_active != 0 AND ad.expire > 1371151608 AND ad.cat_id = '1' AND ad.price <= '10000'
AND auta.rocnik BETWEEN '1950' AND '2013'
AND auta.km BETWEEN '0' AND '500000'
ORDER BY top_expire DESC, program DESC, ad.id DESC LIMIT 0,10) as ad
JOIN pages p ON ad.page_id=p.page_id;
Run Code Online (Sandbox Code Playgroud)
CREATE TABLE `mod_ad` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`user_id` int(10) unsigned NOT NULL,
`page_id` int(10) unsigned NOT NULL,
`cat_id` int(10) unsigned NOT NULL,
`subcat_id` int(10) unsigned NOT NULL,
`program` tinyint(1) unsigned NOT NULL,
`region_id` int(10) unsigned NOT NULL,
`zone_id` int(10) unsigned NOT NULL,
`city_id` int(10) unsigned NOT NULL,
`sort` enum('firm','priv') NOT NULL,
`type` enum('predaj','kúpa','výmena','darujem','h?adám','ponúkam','iné') NOT NULL,
`condition` varchar(24) NOT NULL,
`name` varchar(128) NOT NULL,
`desc` text NOT NULL,
`location` varchar(128) NOT NULL,
`keywords` varchar(255) NOT NULL,
`price` decimal(10,2) NOT NULL,
`price_type` varchar(20) NOT NULL,
`cperson` varchar(128) NOT NULL,
`firmname` varchar(128) NOT NULL,
`zip` varchar(5) NOT NULL,
`email` varchar(255) NOT NULL,
`tel` varchar(20) NOT NULL,
`tel2` varchar(20) NOT NULL,
`web` varchar(255) NOT NULL,
`video` varchar(255) NOT NULL,
`marked_expire` int(11) unsigned NOT NULL,
`top_expire` int(11) unsigned NOT NULL,
`ad_hot_expire` int(11) unsigned NOT NULL,
`ad_border_expire` int(11) unsigned NOT NULL,
`ad_heading_expire` int(11) unsigned NOT NULL,
`ad_weblink_expire` int(11) unsigned NOT NULL,
`active` int(10) unsigned NOT NULL,
`usr_active` int(10) unsigned NOT NULL,
`added` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`archive` int(10) unsigned NOT NULL,
`expire` int(11) unsigned NOT NULL,
`token` varchar(32) NOT NULL,
`views` mediumint(9) NOT NULL,
`ip` varchar(15) NOT NULL,
PRIMARY KEY (`id`),
KEY `user_id` (`user_id`),
KEY `page_id` (`page_id`),
KEY `cat_id` (`cat_id`),
KEY `region_id` (`region_id`),
KEY `zone_id` (`zone_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE `mod_ad_auta` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`ad_id` int(10) unsigned NOT NULL,
`model` int(10) unsigned NOT NULL,
`rocnik` smallint(5) unsigned NOT NULL,
`palivo` varchar(10) NOT NULL,
`karoseria` varchar(12) NOT NULL,
`km` mediumint(8) unsigned NOT NULL,
`prevodovka` varchar(12) NOT NULL,
`farba` varchar(16) NOT NULL,
`metaliza` tinyint(1) unsigned NOT NULL,
`obsah` smallint(5) unsigned NOT NULL,
`vykon` smallint(5) unsigned NOT NULL,
`vybava` text NOT NULL,
PRIMARY KEY (`id`),
KEY `ad_id` (`ad_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
Run Code Online (Sandbox Code Playgroud)
Mik*_*ll' 16
在某些情况下,MySQL 无法使用索引来解析 ORDER BY,尽管它仍然使用索引来查找与 WHERE 子句匹配的行。这些案例包括:
然后继续列出许多阻止 MySQL 使用索引的情况。其中有
- 您在不同的键上使用 ORDER BY
- 用于获取行的键与 ORDER BY 中使用的键不同
可能还有其他人。
为了避免文件排序,您必须找到一种方法来获得您想要的内容,而不会遇到任何这些(许多)记录条件。
你也可以
- 增加 sort_buffer_size 变量的大小。
- 增加 read_rnd_buffer_size 变量的大小。
- 通过将列声明为容纳存储在其中的值所需的大小,每行使用更少的 RAM。
- 将 tmpdir 更改为指向具有大量可用空间的专用文件系统。
(相同的链接。)
另请参阅Optimizing LIMIT Queries 的文档,它与 ORDER BY 交互。