请帮我选择表的索引,以避免运行特定查询时出现的文件归档。
因此,有两个表demo_user
和demo_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
此查询的说明在尝试按q.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 |
+----+-------------+-------+------+---------------+------+---------+------+------+---------------------------------+
所以我的问题是:在运行此类查询时可以采取哪些措施来防止文件排序,因为当两个表中存在大量行时,它会降低性能?
答案 0 :(得分:1)
您已拥有此查询可能使用的所有索引。有两个问题。首先,这绝对不是一个左连接,它是一个内连接,你需要理解为什么这是真的,它应该这样写,即使优化器可能意识到你的意图(尽管表达不同)这将解释为什么更改查询不会更改查询计划。
第二个问题是,你不能指望优化器选择一个具有微小数据集的计划,该计划将与在较大数据集上使用的计划相同。
优化器对“成本”做出决策,并且假设在一小组数据上使用索引的成本相对较高......所以它现在会放弃现在,但不太可能在以后......计划你到这里将随着数据集的变化而改变。