什么更好?子查询或内连接十个表?
一个旧系统已抵达我们的办公室进行一些更改和修复,但它也存在性能问题。我们并不确切知道这种缓慢的根源是什么。
当我们重构旧代码时,我们发现了几个具有以下模式的 SQL 查询(出于示例目的,这些查询被简化):
SELECT
(
SELECT X
FROM A
WHERE A.id = TABLE.id
) AS COLUMN1,
(
SELECT Y
FROM B
WHERE B.id = TABLE.id
) AS COLUMN1,
(
SELECT Z
FROM C
WHERE C.id = TABLE.id
) AS COLUMN1,
...
FROM
TABLE
WHERE
TABLE.id = @param;
这些查询从它们返回的每个列中执行几个内部子查询。
我们计划按照以下模式重写这些查询:
SELECT
A.X, B.Y, C.Z
FROM
TABLE
INNER JOIN A on A.ID = TABLE.ID
INNER JOIN B on B.ID = TABLE.ID
INNER JOIN C on C.ID = TABLE.ID
WHERE
TABLE.id = @param;
使用内部联接,它们更容易阅读和理解,但它真的更快吗?这是更好的编写方式吗? 不幸的是,我们重写的第一个并没有改善查询时间,而是使查询速度变慢了一些。
这是我的问题:我们应该重写所有这些查询吗?这些子查询是完成这项工作的好方法吗?内连接方式更快吗?
An old system have arrived on our office for some changes and fix, but it is also suffering from performance issues. We don't know exactly what is the source of this slowness.
While we were refactoring the old code we found several sql queries with the follow pattern (the queries are simplified for example purpose):
SELECT
(
SELECT X
FROM A
WHERE A.id = TABLE.id
) AS COLUMN1,
(
SELECT Y
FROM B
WHERE B.id = TABLE.id
) AS COLUMN1,
(
SELECT Z
FROM C
WHERE C.id = TABLE.id
) AS COLUMN1,
...
FROM
TABLE
WHERE
TABLE.id = @param;
These queries do several internal sub queries from every column they return.
We are planning to rewrite these queries on the follow pattern:
SELECT
A.X, B.Y, C.Z
FROM
TABLE
INNER JOIN A on A.ID = TABLE.ID
INNER JOIN B on B.ID = TABLE.ID
INNER JOIN C on C.ID = TABLE.ID
WHERE
TABLE.id = @param;
With inner joins they are easier to read and understand, but is it really any faster? Is it the better way to write them?
Unfortunately the first one we rewrote didn't improve the query time, it made the query a bit slower.
Here is my question: should we rewriting all these queries? Are these sub-queries a good way to do this job? Are they faster the the inner-join way?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
如果我正确理解你的问题,那么你正在开始重写一些 SQL 语句,因为你认为它们可能存在问题。
我的建议是停下来,首先确定你的时间目前都花在哪里了。
仅当您发现它位于具有这些标量子选择的查询中并且是由于这些标量子选择所致时,您才应该重写它们。
在那之前:开始追踪和检查。
以下是来自 OTN 的两个线程,用于指导遇到性能问题的人员:
http:// /forums.oracle.com/forums/thread.jspa?messageID=1812597
http://forums.oracle.com/forums/thread.jspa?threadID=863295问候
,
抢。
并且:由于标量子查询缓存,您的原始查询可能比重写的查询快得多使用连接进行查询。
If I understand your question correctly, you are starting an operation to rewrite some of your SQL statements because you THINK there might be an issue with them.
My advice is to stop and first start to determine where your time is currently being spent.
Only after you have found that it's in the queries with those scalar subselects AND it's because of those scalar subselects, you should be rewriting them.
Until then: start tracing and examining.
Here are two threads from OTN that are used to guide people with performance problems:
http://forums.oracle.com/forums/thread.jspa?messageID=1812597
http://forums.oracle.com/forums/thread.jspa?threadID=863295
Regards,
Rob.
And: because of scalar subquery caching, your original query might be a lot faster than a rewritten query using joins.
子查询实际上对每一行运行一次,而联接发生在索引上。
正如您在问题中已经提到的那样,使用联接可以获得更好的可读性和可维护性。
subquery actually runs once for every row whereas the join happens on indexes.
Use joins for better readability and maintainability as you have already mentioned in your questions.
连接将为您提供更好的性能,但我建议在“优化”查询时查看执行计划。
Joins will give you better performance, but I recommend taking a look at the execution plan whenever "optimising" queries.
正如这个答案所主张的,它应该 不影响性能。但是,某些查询优化器可能在 JOIN 上执行得更好,因此您应该在您的系统上进行一些实验。
现在我们来看看完全不同的东西:将每个表
JOIN
连接到下一个表可能比使用TABLE
JOIN
连接所有表更美观,并且可以防止错误每当 id 在一个表中出现多次时:As this answer argues, it should not affect the performance. However, some query optimizers might perform better on JOINs, so you should make some experiments on your system.
And now for something completely different:
JOIN
ing each table to the next one might be more aesthetic thanJOIN
ing all withTABLE
, and prevents errors whenever the id appears more than once in one of the tables:这里内连接更好。原因如下:
1- 在主查询中,您引用/使用子查询中使用的表中的值。加入就是为了这个。您的要求是 - “通过连接不同的表来获取一些值,因为这些值无法从一张表中获得”。
当主查询中未引用子查询中的列时,应使用子查询。
例如:
您在这里询问 - “给我找在部门号 deptno 工作的所有员工”。您不太关心部门中的这个部门。
2-另一个原因是可读性,你已经提到了。
3- 就性能而言,您不必担心,因为优化器知道该怎么做。
有关更多详细信息,请查看此处。
Here inner joining is better. Below are the reasons:
1- In your main query, you are referring/using the values from the table used in sub query. Join is meant for this. Your ask is - "Get me some values by joining different tables as these can not be obtained from one table".
Sub query should be used when columns from sub query is not referred in the main query.
Like:
Here you are asking- "Get me all employees who works in department number deptno". You are not much concerned about this deptno in dept.
2- Another reason is readability, that you already mentioned.
3- Performance-wise you need not worry as optimizer knows what to do.
For more details, please check here.