4

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

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

4

2 回答 2

2

建议:索引表如下:

ALTER TABLE tbl_map ADD INDEX (tbl_1_id,rating,tbl_2_id);
于 2012-05-15T16:07:54.843 回答
2

按照 Rolando 的说法,是的,您肯定需要在地图表上建立一个索引,但我会扩展到还包括 tbl_2_id,它用于表 2 的 ID 的 ORDER BY 子句(它与地图在同一个表中,所以只需使用它此外,由于索引现在包含所有 3 个字段,并且基于键搜索的 ID 和评级为 null(或不为空)的条件,因此第三个元素已经为您的 ORDER BY 子句提供了它们。

索引(tbl_1_id,评级,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 
于 2012-05-15T16:31:39.727 回答