【发布时间】:2011-10-27 06:17:04
【问题描述】:
我有一张桌子items 和一张桌子item_attributes。
为简单起见,假设我的表项有一个列id 和一个列name。
当然,id 列上有一个索引。
item_attributes 表包含 id、item_id、attribute_name 和 attribute_value 列,并且索引为 ON attrubute_name
现在我想在不使用连接的情况下查询具有特定属性的所有项目。
我使用以下查询来做到这一点:
SELECT *
FROM items i
WHERE i.id IN (
SELECT item_id
FROM item_attributes a
WHERE a.attribute_name = 'SomeAttribute'
AND a.attribute_value = 'SomeValue'
)
子查询本身运行速度很快。
如果我先执行查询本身并将结果用于 IN 查询
SELECT *
FROM items i
WHERE i.id IN (1,3,5,7,10,...)
它也很快。
但是,结合查询非常非常慢(> 2 秒。) 如果我调查查询计划,我就会明白原因:MySQL 对 items 表进行全表扫描,而不是先执行子查询并将结果用于索引查询。
1, 'PRIMARY', 'items', 'ALL', '', '', '', '', 149726, 'Using where'
2, 'DEPENDENT SUBQUERY', 'item_attributes', 'index_subquery', 'IDX_ATTRIBUTE_NAME', 'IDX_ATTRIBUTE_NAME', '4', 'func', 1, 'Using where'
有没有办法优化这个查询?我知道子查询总是只返回一个小的结果集(
【问题讨论】:
-
是什么促使您在不使用
JOIN的情况下执行此操作? -
我不能使用join,因为这只是整个画面的一小部分。我将 C# 与 ORM 一起使用,然后将
WHERE master.primarykey IN (dynamic subquery)片段添加到内存中现有的查询对象中,该对象稍后将转换为普通 SQL。我不能使用 JOIN,因为我需要添加一个 group by 子句,但这会限制调用函数。 -
@Schla:在你的模型中,一个项目可以有两条具有相同
attribute_name的记录吗? -
@Quassino:当然,任何物品都可以有一个名称为
InStock的属性。 -
这不是我问的。一个项目(一个项目)可以有两个名为
InStock的属性吗?
标签: mysql query-optimization explain