使用IN子查询改善MySQL查询

编程入门 行业动态 更新时间:2024-10-23 01:49:04
本文介绍了使用IN子查询改善MySQL查询的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我有一张桌子items和一张桌子item_attributes.

I hava a table items and a table item_attributes.

为简单起见,假设我的表格项具有列id和列name. 当然,在id列上有一个索引.

For simplicity let's say my table item has a column id and a column name. Of cource there is a index on the id column.

item_attributes表具有列id,item_id,attribute_name和attribute_value以及索引为attrubute_name

the item_attributes table has the columns id, item_id, attribute_name and attribute_value and an index ON attrubute_name

现在,我想在不使用联接的情况下查询具有特定属性的所有项目.

Now I want to query all items with a specific attribut without using a join.

我通过以下查询进行此操作:

I do this with the following query:

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' )

SubQuery本身运行速度很快.

the SubQuery itself runs fast.

如果我先执行查询本身,然后将结果用于IN查询

If I execute the query itself first and use the result for an IN query

SELECT * FROM items i WHERE i.id IN (1,3,5,7,10,...)

它也很快.

但是,合并查询的速度非常非常慢(> 2秒). 如果我调查查询计划,我会明白为什么:MySQL对items表执行全表扫描,而不是先执行子查询并使用结果进行索引查询.

However, combined the query is very, very slow (>2 secs.) If I investigate the query plan I see why: MySQL does a full table scan on the items table instead of executing the subquery first and using the result for an index query.

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'

有没有一种方法可以优化此查询?我知道子查询将始终只返回一个小的结果集(<100行).

Is there a way to optimize this query? I know that the subquery will always return only a small resultset (<100 rows).

推荐答案

MySQL无法在IN子句中切换引导表和从动表.这将在6.0 中进行了纠正.

MySQL cannot switch the leading and the driven table in the IN clause. This is going to be corrected in 6.0.

现在,您可以像这样重写它(需要JOIN):

For now, you can rewrite it like this (requires a JOIN):

SELECT i.* FROM ( SELECT DISTINCT item_id FROM item_attributes a WHERE a.attribute_name = 'SomeAttribute' AND a.attribute_value = 'SomeValue' ) ai JOIN items i ON i.id = ai.item_id

由于使用的是EAV模型,因此您可能希望在(attribute_name, item_id)上创建唯一索引,在这种情况下,可以使用普通联接:

Since you are using the EAV model you may want to make a unique index on (attribute_name, item_id) in which case you can use a plain join:

SELECT i.* FROM item_attributes ai JOIN items i ON i.id = ai.item_id WHERE a.attribute_value = 'SomeValue' AND a.attribute_name = 'SomeAttribute'

更多推荐

使用IN子查询改善MySQL查询

本文发布于:2023-06-01 10:28:26,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/412970.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:MySQL

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!