SQL 游标查询或两个单独的查询:哪个更有效?

发布于 2024-10-25 16:14:25 字数 213 浏览 0 评论 0原文

我正在努力使 PHP 中处理消息树的一些代码更加高效。数据存储在 SQL 数据库中,目前每条消息必须执行 2 次 SQL 查询,一次查找数据,一次更新数据。我想我有办法通过单个查询来完成此操作,但它使用游标,我听说游标比其他 SQL 方法慢得多。

有谁知道使用游标执行一个 SQL 查询是否仍然会更有效,或者坚持使用当前方法(对每条消息使用选择和更新查询以及 PHP 将查询绑定在一起)会更好吗?

I'm working on trying to make a bit of code dealing with a message tree in PHP more efficient. The data is stored in a SQL database, and at present has to do 2 SQL queries per message, one to find the data and one to update the data. I think I have a way to get this done with a single query, but it uses cursors which I've heard are much slower than other SQL methods.

Does anyone know whether it would still be more efficient to do one SQL query which uses cursors, or would it be better to stick with the current method which uses a select and an update query per message and PHP to tie the queries together?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

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

发布评论

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

评论(1

爱情眠于流年 2024-11-01 16:14:25

同意@Catcall - 在没有看到代码的情况下,很难有意义地回答这个问题。

然而,从广义上讲,人们经常说游标比其他 SQL 方法慢的原因是因为一些开发人员在基于集合的操作可以工作的地方使用游标。

例如,如果您的计划是(在伪代码中,在没有实际的数据库引擎或模式的情况下)

create cursor RecordsToUpdate
as
select *
from UserTable
where name like 'Codd%'

foreachRecord in RecordsToUpdate
  set record.lastUpdatedDate = today
next

(希望)显然您可以通过执行来实现相同的目标

update UserTable
set lastUpdatedDate = today
where name like 'Codd%'

但是,在某些情况下基于集合的操作是不可能的,然后 - 再次,从广义上讲 - 创建游标、执行逻辑并关闭游标会更有效 - 最好是在存储过程或其他内容中。这种方法限制了将数据发送回 PHP 服务器的网络开销。

话虽如此,在大多数情况下,您不会注意到现实场景中的差异。另外,值得指出的是,如果您的数据库负载很重,或者您的查询执行缓慢(例如,通过迭代具有数百万条记录的游标),则此方法可能会造成数据库服务器瓶颈。一般来说,如果可能的话,您希望避免数据库上有长时间运行的作业 - 最好将它们分成许多小作业。

Agree with @Catcall - without seeing the code, it's hard to answer this question meaningfully.

However, in broad terms, the reason people often say cursors are slower than other SQL methods is because some developers use cursors where a set based operation would work.

For instance, if your plan is (in pseudo code, in the absence of actual DB engine or schema)

create cursor RecordsToUpdate
as
select *
from UserTable
where name like 'Codd%'

foreachRecord in RecordsToUpdate
  set record.lastUpdatedDate = today
next

It's (hopefully) obvious that you can achieve the same by executing

update UserTable
set lastUpdatedDate = today
where name like 'Codd%'

However, there are cases where set-based operations just aren't possible, and then - again, broadly speaking - it will be more efficient to create a cursor, execute your logic, and close the cursor - ideally within a stored procedure or something. This approach limits the network overhead of sending data back to your PHP server.

Having said all that - in most cases, you won't notice the difference in real-world scenarios. Also, it's worth pointing out that if your database is heavily loaded, or your query executes slowly (e.g. by iterating over a cursor with millions of records), this approach may create a DB server bottleneck. Broadly speaking, you want to avoid having long-running jobs on your database if at all possible - it's better to split them up into lots of small jobs.

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