Mysql 在连接查询中按极慢的顺序排序
Mysql order by extremely slow in joined query
查询:
SELECT `files`.*, `file_status`.`downloaders` FROM `files`
INNER JOIN `file_status` ON `files`.file_id = `file_status`.file_id
WHERE `files`.type`> 0 AND `files`.type` <= 2
ORDER BY `downloaders` DESC
LIMIT 50
表格:
CREATE TABLE IF NOT EXISTS `files` (
`file_id` int(11) NOT NULL,
`name` varchar(150) COLLATE utf8_unicode_ci NOT NULL,
`type` int(11) NOT NULL,
`description` text COLLATE utf8_unicode_ci NOT NULL,
`user` varchar(35) COLLATE utf8_unicode_ci NOT NULL,
`size` bigint(20) NOT NULL,
`upload_time` int(11) NOT NULL,
PRIMARY KEY (`file_id`),
KEY `type` (`type`),
FULLTEXT KEY `name_full` (`name`),
FULLTEXT KEY `description` (`description`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE IF NOT EXISTS `file_status` (
`file_id` int(11) NOT NULL,
`downloaders` int(11) NOT NULL,
`complete` int(11) NOT NULL,
`last_update` int(11) NOT NULL,
PRIMARY KEY (`file_id`),
KEY `downloaders` (`downloaders`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
此查询对表中的 20 万个条目执行 5 秒。表格稍后会有更多条目,所以我担心这将是一场彻底的灾难..
如果我通过正常执行删除订单。
有什么方法可以加快速度(除了将列移到第一个表之外)吗?
解释:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE files ALL PRIMARY,type NULL NULL NULL 256956 Using where; Using temporary; Using filesort
1 SIMPLE file_status eq_ref PRIMARY PRIMARY 4 x.files.file_id 1 NULL
非常笨拙:
SELECT * FROM `files` AS x INNER JOIN (
SELECT `file_id`, downloaders FROM `file_status` WHERE `file_id` IN (
SELECT `file_id` FROM `files` WHERE `type`>0 AND `type`<=2
) ORDER BY `downloaders` DESC LIMIT 50
) as y ON x.`file_id` = y.`file_id`
INNER JOIN `file_status` ON x.`file_id` = `file_status`.`file_id`
第一个内部连接是因为 mysql 表示它不支持子查询中的 LIMIT
我们对每个 table 使用子查询以使 mysql 使用正确的索引(键)
这会立即执行
查询:
SELECT `files`.*, `file_status`.`downloaders` FROM `files`
INNER JOIN `file_status` ON `files`.file_id = `file_status`.file_id
WHERE `files`.type`> 0 AND `files`.type` <= 2
ORDER BY `downloaders` DESC
LIMIT 50
表格:
CREATE TABLE IF NOT EXISTS `files` (
`file_id` int(11) NOT NULL,
`name` varchar(150) COLLATE utf8_unicode_ci NOT NULL,
`type` int(11) NOT NULL,
`description` text COLLATE utf8_unicode_ci NOT NULL,
`user` varchar(35) COLLATE utf8_unicode_ci NOT NULL,
`size` bigint(20) NOT NULL,
`upload_time` int(11) NOT NULL,
PRIMARY KEY (`file_id`),
KEY `type` (`type`),
FULLTEXT KEY `name_full` (`name`),
FULLTEXT KEY `description` (`description`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE IF NOT EXISTS `file_status` (
`file_id` int(11) NOT NULL,
`downloaders` int(11) NOT NULL,
`complete` int(11) NOT NULL,
`last_update` int(11) NOT NULL,
PRIMARY KEY (`file_id`),
KEY `downloaders` (`downloaders`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
此查询对表中的 20 万个条目执行 5 秒。表格稍后会有更多条目,所以我担心这将是一场彻底的灾难..
如果我通过正常执行删除订单。
有什么方法可以加快速度(除了将列移到第一个表之外)吗?
解释:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE files ALL PRIMARY,type NULL NULL NULL 256956 Using where; Using temporary; Using filesort
1 SIMPLE file_status eq_ref PRIMARY PRIMARY 4 x.files.file_id 1 NULL
非常笨拙:
SELECT * FROM `files` AS x INNER JOIN (
SELECT `file_id`, downloaders FROM `file_status` WHERE `file_id` IN (
SELECT `file_id` FROM `files` WHERE `type`>0 AND `type`<=2
) ORDER BY `downloaders` DESC LIMIT 50
) as y ON x.`file_id` = y.`file_id`
INNER JOIN `file_status` ON x.`file_id` = `file_status`.`file_id`
第一个内部连接是因为 mysql 表示它不支持子查询中的 LIMIT
我们对每个 table 使用子查询以使 mysql 使用正确的索引(键)
这会立即执行