简体   繁体   English

MySQL优化 - 大型表连接

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM