SQL查询执行时间很快,但获取行很慢
这是一个由两部分组成的问题,但首先是一些背景信息:
我在 Sybase 中有一个 TSQL 查询,报告执行时间为 0.328 秒,但检索大约 5000 行需要大约 20-30 秒。该查询有两个子查询和一个左外连接。
该查询大致如下:
SELECT CustomerContact.Id, Customer.Name, ...
, CustomerContacts.LastName, CustomerContacts.FirstName
, ( SELECT max(LastModified)
FROM ContactPhone
WHERE ContactPhone.ContactID = CustomerContact.ID
) as PhoneLastModified
, ( SELECT max(LastModified)
FROM ContactEmail
WHERE ContactEmail.ContactID = CustomerContact.ID
) as EmailLastModified
FROM CustomerContacts
LEFT OUTER JOIN Customer
ON Customer.ID = CustomerContact.CustomerId
WHERE (PhoneLastModified > '2011-01-01'
OR EmailLastModified > '2011-01-01')
我正在做的是根据任何关联联系信息的上次修改日期选择客户记录。对于 CustomerContact 中的任何给定行,ContactPhone 和 ContactEmail 可以包含 x 条记录。 Customer 表与 CustomerContact 是一对一的。
现在我的问题是:
为什么 Sybase 报告执行时间为 0.328 秒,但实际上检索查询中的行需要接近 30 秒?
我可以做什么来优化这个查询?
我的第一个想法是向 LastModified 列添加索引,但我正在处理少量记录。
我的第二个想法是子查询正在减慢速度,我应该将它们转换为联接。但我无法在连接条件中使用聚合函数 max,那么如何仅获取连接中的最大行呢?
谢谢
This is a two part question, but first some background information:
I have a TSQL query in Sybase that reports an execution time of 0.328 seconds, however its taking around 20-30 seconds to retrieve approximately 5000 rows. The query has two subquery's and a left outer join.
The query looks roughly like this:
SELECT CustomerContact.Id, Customer.Name, ...
, CustomerContacts.LastName, CustomerContacts.FirstName
, ( SELECT max(LastModified)
FROM ContactPhone
WHERE ContactPhone.ContactID = CustomerContact.ID
) as PhoneLastModified
, ( SELECT max(LastModified)
FROM ContactEmail
WHERE ContactEmail.ContactID = CustomerContact.ID
) as EmailLastModified
FROM CustomerContacts
LEFT OUTER JOIN Customer
ON Customer.ID = CustomerContact.CustomerId
WHERE (PhoneLastModified > '2011-01-01'
OR EmailLastModified > '2011-01-01')
What I am doing is selecting customer records based on the last modified date of any associated contact information. ContactPhone and ContactEmail can contain x number of records for any given row in CustomerContact. The Customer table is one-to-one with CustomerContact.
Now my question:
How come Sybase reports an execution time of 0.328 seconds, but it's actually taking closer to 30 seconds to retrieve the rows in the query?
What can I do to optimize this query?
My first thought is to add indexes to the LastModified columns, but I'm dealing with a small number of records.
My second thought is that the subquery's are slowing things down, and that I should convert them into joins. But I can't use the aggregate function max in the Join condition, so how do I get only the max row in my join?
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我猜测 select 子句中的 2 个相关子查询在返回行之前不会执行。一般来说,应该避免相关子查询,因为它们往往很慢,当然总有例外!
尝试将 ContactPhone 和 Contact Email 移动到连接的子查询中。
I'm guessing that the 2 correlated subqueries in the select clause don't execute until the rows are returned. In general correlated subqueries should be avoided, as they tend to be slow, of course there are always exceptions!
Try moving ContactPhone and Contact Email into a joined subquery.
我现在看到他使用的是 SYBASE 而不是 SQL Server(TSQL 也可以是),但我会将答案留给其他使用 MS 产品的人。
这是 CTE 版本。与 Paul 的版本相同,但更容易阅读:
I see now he is using SYBASE not SQL Server (TSQL could be either), but I'll leave the answer for others who are using the MS product.
Here is the CTE version. Works the same as Paul's version but slightly easier to read: