Mysql 优化索引以避免使用文件排序

Mysql 优化索引以避免使用文件排序,mysql,Mysql,请帮助我为表选择索引,以避免在运行特定查询时发生文件排序 因此,有两个表demo\u user和demo\u question: CREATE TABLE `demo_user` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `name` VARCHAR(50) NOT NULL, `age` INT(11) NOT NULL, PRIMARY KEY (`id`), INDEX `age` (`age`) ) COLLA

请帮助我为表选择索引,以避免在运行特定查询时发生文件排序

因此,有两个表
demo\u user
demo\u question

CREATE TABLE `demo_user` (
    `id` INT(11) NOT NULL AUTO_INCREMENT,
    `name` VARCHAR(50) NOT NULL,
    `age` INT(11) NOT NULL,
    PRIMARY KEY (`id`),
    INDEX `age` (`age`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB;

CREATE TABLE `demo_question` (
    `id` INT(11) NOT NULL AUTO_INCREMENT,
    `userId` INT(11) NOT NULL,
    `createdAt` DATETIME NOT NULL,
    `question` VARCHAR(50) NOT NULL,
    PRIMARY KEY (`id`),
    INDEX `userId` (`userId`),
    INDEX `createdAt` (`createdAt`),
    CONSTRAINT `FK_demo_question_demo_user` FOREIGN KEY (`userId`) REFERENCES     `demo_user` (`id`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB;
一些样本数据:

INSERT INTO `demo_user` VALUES ('u1', 20);
INSERT INTO `demo_user` VALUES ('u2', 25);
INSERT INTO `demo_user` VALUES ('u3', 27);
INSERT INTO `demo_user` VALUES ('u4', 33);
INSERT INTO `demo_user` VALUES ('u5', 19);
INSERT INTO `demo_question` VALUES (2, '2014-01-19 15:17:13', 'q1');
INSERT INTO `demo_question` VALUES (3, '2014-01-19 15:17:43', 'q2');
INSERT INTO `demo_question` VALUES (5, '2014-01-19 15:17:57', 'q3');
在这些表上,我尝试运行以下查询:

select *
from demo_question q
left join demo_user u on q.userId = u.id
where u.age >= 20 and u.age <= 30
order by q.createdAt desc

因此,我的问题是:在运行这样的查询时,如何防止文件排序,因为当两个表中都有大量行时,这会降低性能?

您已经拥有此查询可能使用的所有索引。有两个问题。首先,这绝对不是一个左连接,它是一个内部连接,您需要理解为什么这是真的,并且应该这样写,即使优化器可能意识到您的意图(尽管表达方式不同),这将解释为什么更改查询不会更改查询计划

第二个问题是,您不能期望优化器选择一个具有小数据集的计划,该计划将与在较大数据集上使用的计划相同


优化器根据“成本”做出决策,并且假设在一小部分数据上使用索引的成本相对较高。。。所以现在它会放弃那个选项,但以后不太可能。。。您在此处获得的计划将随着数据集的更改而更改。

尝试使用内部连接而不是左连接,以防mysql太笨而没有注意到它正在这样做。@Denis不幸的是,内部连接没有改变任何东西。试着在演示问题中将两列放入索引,而不是两个索引,即索引
userId
userId
)变为索引
userId
userId
createdAt
)很好的解释。谢谢你抽出时间。
+----+-------------+-------+------+---------------+------+---------+------+------+---------------------------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra                           |
+----+-------------+-------+------+---------------+------+---------+------+------+---------------------------------+
|  1 | SIMPLE      | q     | ALL  | userId        | NULL | NULL    | NULL |    3 | Using  temporary; Using filesort |
|  1 | SIMPLE      | u     | ALL  | PRIMARY,age   | NULL | NULL    | NULL |    5 | Using  where; Using join buffer  |
+----+-------------+-------+------+---------------+------+---------+------+------+---------------------------------+