什么更好?子查询或内连接十个表?

发布于 2024-10-16 05:36:11 字数 854 浏览 3 评论 0原文

一个旧系统已抵达我们的办公室进行一些更改和修复,但它也存在性能问题。我们并不确切知道这种缓慢的根源是什么。

当我们重构旧代码时,我们发现了几个具有以下模式的 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

黑寡妇 2024-10-23 05:36:11

如果我正确理解你的问题,那么你正在开始重写一些 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.

叶落知秋 2024-10-23 05:36:11

子查询实际上对每一行运行一次,而联接发生在索引上。

正如您在问题中已经提到的那样,使用联接可以获得更好的可读性和可维护性。

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.

烟凡古楼 2024-10-23 05:36:11

连接将为您提供更好的性能,但我建议在“优化”查询时查看执行计划。

Joins will give you better performance, but I recommend taking a look at the execution plan whenever "optimising" queries.

平安喜乐 2024-10-23 05:36:11

正如这个答案所主张的,它应该 不影响性能。但是,某些查询优化器可能在 JOIN 上执行得更好,因此您应该在您的系统上进行一些实验。

现在我们来看看完全不同的东西:将每个表JOIN连接到下一个表可能比使用TABLEJOIN连接所有表更美观,并且可以防止错误每当 id 在一个表中出现多次时:

SELECT
    A.X, B.Y, C.Z
FROM
    TABLE
    INNER JOIN A on A.ID = TABLE.ID
    INNER JOIN B on A.ID = B.ID
    INNER JOIN C on B.ID = C.ID
WHERE
    TABLE.id = @param;

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: JOINing each table to the next one might be more aesthetic than JOINing all with TABLE, and prevents errors whenever the id appears more than once in one of the tables:

SELECT
    A.X, B.Y, C.Z
FROM
    TABLE
    INNER JOIN A on A.ID = TABLE.ID
    INNER JOIN B on A.ID = B.ID
    INNER JOIN C on B.ID = C.ID
WHERE
    TABLE.id = @param;
树深时见影 2024-10-23 05:36:11

这里内连接更好。原因如下:

1- 在主查询中,您引用/使用子查询中使用的表中的值。加入就是为了这个。您的要求是 - “通过连接不同的表来获取一些值,因为这些值无法从一张表中获得”。

当主查询中未引用子查询中的列时,应使用子查询。
例如:

select * from emp where deptno in ( select deptno from dept ); 

您在这里询问 - “给我找在部门号 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:

select * from emp where deptno in ( select deptno from dept ); 

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文