这里开始是所涉及表格的简化版本。
tbl_map
有大约4,000,000行,tbl_1
大约有120行,tbl_2
包含大约5,000,000行。我知道不应该考虑数据,因为Google,Yahoo!等使用了更大的数据集。所以我只是假设我错过了什么。
CREATE TABLE `tbl_map` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`tbl_1_id` bigint(20) DEFAULT '-1',
`tbl_2_id` bigint(20) DEFAULT '-1',
`rating` decimal(3,3) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `tbl_1_id` (`tbl_1_id`),
KEY `tbl_2_id` (`tbl_2_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE `tbl_1` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE `tbl_2` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`data` varchar(255) NOT NULL DEFAULT '',
PRIMARY KEY (`id`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
感兴趣的查询:而不是ORDER BY RAND()
,ORDERY BY t.id DESC
。查询花费的时间长达5~10秒,并在用户查看此页面时引起相当长的等待。
EXPLAIN SELECT t.data, t.id , tm.rating
FROM tbl_2 AS t
JOIN tbl_map AS tm
ON t.id = tm.tbl_2_id
WHERE tm.tbl_1_id =94
AND tm.rating IS NOT NULL
ORDER BY t.id DESC
LIMIT 200
1 SIMPLE tm ref tbl_1_id, tbl_2_id tbl_1_id 9 const 703438 Using where; Using temporary; Using filesort
1 SIMPLE t eq_ref PRIMARY PRIMARY 8 tm.tbl_2_id 1
我只想加快查询速度,确保我有适当的索引等。 我感谢DB Gurus的任何建议!谢谢。
答案 0 :(得分:2)
ALTER TABLE tbl_map ADD INDEX (tbl_1_id,rating,tbl_2_id);
答案 1 :(得分:2)
根据Rolando的说法,是的,你肯定需要地图表上的索引,但我会扩展到包括tbl_2_id,它是表2的ID的ORDER BY子句(与地图在同一个表中,所以只使用该索引。此外,由于索引现在包含所有3个字段,并且基于键搜索的ID和评级为null(或不符号)的标准,因此第3个元素已将它们用于ORDER BY子句
INDEX(tbl_1_id,rating,tbl_2_id);
然后,我将查询为
SELECT STRAIGHT_JOIN
t.data,
t.id ,
tm.rating
FROM
tbl_map tm
join tbl_2 t
on tm.tbl_2_id = t.id
WHERE
tm.tbl_1_id = 94
AND tm.rating IS NOT NULL
ORDER BY
tm.tbl_2_id DESC
LIMIT 200