我正在针对2个表运行查询,并且由于某种原因它没有使用索引。我无法理解我的生活。
以下是我的表:table1
和table2
。表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有100多万行,并涉及产品类别。表字段结构如下所示:
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)
,但结果仍未改变。如果这是一个随机使用的查询,这并不重要,但是这个查询每天都会被击中数万次。
我在这里做错了,这个查询没有使用可用的索引来大量减少行数?
我希望我提供了正确的信息。提前谢谢。
答案 0 :(得分: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_id
和category_id
上设置单独的索引是不够的。但是,如果您在(category_id, product_id)
上有复合索引,则可以删除(category_id)
上的索引,除非它是唯一索引(如主键)。