[英]MySQL optimization - large table joins
To start out here is a simplified version of the tables involved. 从这里开始是所涉及的表的简化版本。
tbl_map
has approx 4,000,000 rows, tbl_1
has approx 120 rows, tbl_2
contains approx 5,000,000 rows. tbl_map
有大约4,000,000行, tbl_1
有大约120行, tbl_2
包含大约5,000,000行。 I know the data shouldn't be consider that large given that Google, Yahoo!, etc use much larger datasets. 我知道不应该考虑数据,因为Google,Yahoo!等使用了更大的数据集。 So I'm just assuming that I'm missing something. 所以我只是假设我错过了什么。
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;
The Query in interest: also, instead of ORDER BY RAND()
, ORDERY BY t.id DESC
. 感兴趣的查询:而不是ORDER BY RAND()
, ORDERY BY t.id DESC
。 The query is taking as much as 5~10 seconds and causes a considerable wait when users view this page. 查询花费的时间长达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
I would just liked to speed up the query, ensure that I have proper indexes, etc. I appreciate any advice from DB Gurus out there! 我只是想加快查询速度,确保我有适当的索引等等。我很欣赏DB Gurus的任何建议! Thanks. 谢谢。
ALTER TABLE tbl_map ADD INDEX (tbl_1_id,rating,tbl_2_id);
As per Rolando, yes, you definitely need an index on the map table but I would expand to ALSO include the tbl_2_id which is for your ORDER BY clause of Table 2's ID (which is in the same table as the map, so just use that index. Also, since the index now holds all 3 fields, and is based on the ID of the key search and criteria of null (or not) of rating, the 3rd element has them already in order for your ORDER BY clause. 根据Rolando的说法,是的,你肯定需要在地图表上有一个索引,但我会扩展到包括tbl_2_id,它是表2的ID的ORDER BY子句(与地图在同一个表中,所以只需使用它此外,由于索引现在包含所有3个字段,并且基于密钥搜索的ID和评级为null(或不符号)的标准,因此第3个元素已经按顺序存储了ORDER BY子句。
INDEX (tbl_1_id,rating, tbl_2_id); INDEX(tbl_1_id,rating,tbl_2_id);
Then, I would just have the query as 然后,我将查询为
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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.