MySQL 中子查询的优化程度如何?
我的问题很长但很简单。我有以下类型的查询:
select obj from table where condition1 and obj in (
select obj from table where condition2 and obj in (
select obj from table where condition3 and obj in (
...
)))
该查询需要很长时间。我担心 MySQL 按以下方式执行此查询(为简单起见,我们只考虑一个子查询):
select obj from table1 where condition1 and obj in (select obj from table2 where condition2)
MySQL 遍历表 1 的行。如果满足 condition1
,它将开始循环子查询获得的集合中的对象。如果存在考虑的对象,则将其添加到“最终”对象列表中。
我的问题是上面的例子有一个循环。如果我有两个子查询,我就会有一个循环中的循环。如果每个循环大约有 10 000 个周期,我就会遇到灾难。
我的解决方案是找到n组(每组对应一个select
)。然后我独立地对每个集合进行循环(因此,我没有循环中的循环)。类似的事情。
dictionary = []
for (elem in set1) {
dictionary[elem] += 1
}
for (elem in set2) {
dictionary[elem] += 1
}
for (elem in set3) {
dictionary[elem] += 1
}
然后我对字典的所有元素再进行一次循环,并仅选择在所有集合中找到的键:
finalSet = []
for (elem in dictionary) {
if (dictionary[elem]==numberOfSets) {
finalSet.add(elem)
}
}
所以,我的问题是 MySQL 以我希望它优化的方式进行了优化(上面描述的方式)。或者它会在循环中产生循环......
添加
我只是认为我可以通过重新制定查询来实现所需的优化。而不是:
select obj from table where condition1 and obj in (
select obj from table where condition2 and obj in (
select obj from table where condition3 and obj in (
...
)))
我应该写:
select obj from table where condition1
and obj in (select obj from table where condition2)
and obj in (select obj from table where condition3)
...
My question is long but simple. I have queries of the following kind:
select obj from table where condition1 and obj in (
select obj from table where condition2 and obj in (
select obj from table where condition3 and obj in (
...
)))
This query takes a very long time. I am afraid that MySQL performs this query in the following way (for simplicity let's consider just one sub-query):
select obj from table1 where condition1 and obj in (select obj from table2 where condition2)
The MySQL goes through rows of the table 1. If condition1
is fulfilled it starts a loop over the object from the set obtained by the sub-query. If there is a considered object, it is added to the "final" list of objects.
My problem is that the above example has a loop in a loop. And if I have two sub-queries I have a loop in a loop in a loop. If every loop has about 10 000 cycles, I have a disaster.
My solution is to find n sets (every set corresponds to one select
). Then I make a loop over every set independently (so, I do not have loops in loops). Something like that.
dictionary = []
for (elem in set1) {
dictionary[elem] += 1
}
for (elem in set2) {
dictionary[elem] += 1
}
for (elem in set3) {
dictionary[elem] += 1
}
Then I make one more loop over all elements of the dictionary
and select only those keys that were found in all sets:
finalSet = []
for (elem in dictionary) {
if (dictionary[elem]==numberOfSets) {
finalSet.add(elem)
}
}
So, my question is MySQL is optimized in a way I want it to be optimized (above described way). Or it produce loops in loops in loops....
ADDED
I just thought that may be I can achieve the desired optimization by reformulation of my query. Instead of:
select obj from table where condition1 and obj in (
select obj from table where condition2 and obj in (
select obj from table where condition3 and obj in (
...
)))
I should write:
select obj from table where condition1
and obj in (select obj from table where condition2)
and obj in (select obj from table where condition3)
...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
使用 EXPLAIN 查看 MySQL 如何执行查询并查看 JOIN 来重写查询。
目标字段上的索引会加快速度,请检查 EXPLAIN。
Use EXPLAIN to see how MySQL executes the query and take a look at JOIN's to rewrite the query.
Indexes on the obj-fields will speed things up, check EXPLAIN.
子查询不太适合优化。如果可以使用其他方式,请避免对任何应用程序进行子查询。你最好使用以下查询:
select t1.obj
从表 t1
t1.obj = t2.obj 上的内连接表 t2
和 t2.condition='条件'
t3.obj = t1.obj 上的内连接表 t3
and t3.condition='条件'
Sub query is not too good for optimization. avoid subs queries for any application if it can use another way. you better use this following queries:
select t1.obj
from table t1
inner join table t2 on t1.obj = t2.obj
and t2.condition='condition'
inner join table t3 on t3.obj = t1.obj
and t3.condition='Condition'