MySQL优化 - 大型表连接

时间:2012-05-15 15:57:08

标签: mysql query-optimization

这里开始是所涉及表格的简化版本。

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的任何建议!谢谢。

2 个答案:

答案 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