0

我正在对 2 个表运行查询,但由于某种原因它没有使用索引。我一辈子都想不通。

这是我的表:table1table2。表 1 是包含 154 行的类别列表。表 1 的表结构如下所示:

category_id (int11) - also has an index on it
name (varchar30) - also has an index on it
urltext (text)
nametext (text)

category_id     name    urltext   nametext
1           category1    blahblah     blahblah
2           category2    blahblah     blahblah
3           category3    blahblah     blahblah
4           category4    blahblah     blahblah
etc to rows
154           category154    blahblah     blahblah

表 2 有 1+ 百万行,并且与产品类别相关。表字段结构如下所示:

row_id (bigint11) - also has an index
category_id (int3) - also has an index
product_id (int9) - also has an index

表 2 中的数据如下所示:

row_id     category_id     product_id 
1               1            123456
2               4            123456
3               17            456789
4               42            456789
5               7            456789
6               88            888555

这是我的查询:

select * 
from table2 
INNER JOIN table1 
ON table2.category_id=table1.category_id 
where table2.product_id = 123456;

现在,当我对此查询进行解释时:

id   select_type  table type  possible_keys     key       key_len  ref                 rows  Extra
1    simple       table1 ALL    PRIMARY          NULL      NULL     NULL                 154
1    simple       table2 ref    product_id,...   poduct_id  10      category_id, const   1     Using Where

任何产品通常只涉及 1 到 4 个不同的类别。因此,您会认为如果正确使用索引,而不是在解释结果中看到 table1 的 154 行,您会看到最多 4 行。

我最初将 table1.name 设置为text而不是varchar(30),但结果仍然没有改变。如果这是一个随机使用的查询,这并不重要,但是这个查询每天都会被点击数万次。

我在这里做错了什么,这个查询没有使用可用的索引来大量减少行数?

我希望我提供了正确的信息。提前致谢。

4

1 回答 1

1

您的查询可以重新格式化为:

SELECT *
FROM table2
INNER JOIN table1 ON table2.category_id = table1.category_id
WHERE table2.product_id = 123456

为了使其快速,应存在以下索引:

table1(category_id)

快速查找table1.category_id

table2(category_id, product_id)

或者

table2(product_id, category_id)

这个多列(复合)索引将同时满足JOIN条件和WHERE条件。

请注意,在product_idand上有单独的索引category_id是不够的。但是,如果您有复合索引 on (category_id, product_id),您可以删除索引 on (category_id),除非它是唯一索引(如主键)。

于 2013-04-01T07:53:40.857 回答