PHP mySQL—何时是断开与数据库连接的最佳时间?

时间:2022-10-23 18:09:08

I use lazy connection to connect to my DB within my DB object. This basically means that it doesn't call mysql_connect() until the first query is handed to it, and it subsequently skips reconnecting from then on after.

我使用惰性连接在我的DB对象中连接到我的DB。这基本上意味着,在第一个查询被提交给它之前,它不会调用mysql_connect(),随后它会跳过从那时开始的重新连接。

Now I have a method in my DB class called disconnectFromDB() which pretty much calls mysql_close() and sets $_connected = FALSE (so the query() method will know to connect to the DB again). Should this be called after every query (as a private function) or externally via the object... because I was thinking something like (code is an example only)

现在我的DB类中有一个名为disconnectFromDB()的方法,它几乎调用mysql_close()并设置$_connected = FALSE(因此query()方法将知道再次连接到DB)。应该在每个查询(作为私有函数)之后调用它,还是通过对象从外部调用它……因为我在想(代码就是一个例子)

$students = $db->query('SELECT id FROM students');

$teachers = $db->query('SELECT id FROM teachers');

Now if it was closing after every query, would this slow it down a lot as opposed to me just adding this line to the end

如果它在每次查询后都结束了,会不会让它慢下来,而不是我把这一行加到最后

$db->disconnectFromDB();

Or should I just include that line above at the very end of the page?

或者我应该把这一行写在页面的最后吗?

What advantages/disadvantages do either have? What has worked best in your situation? Is there anything really wrong with forgetting to close the mySQL connection, besides a small loss of performance?

两者都有什么优点/缺点?在你的情况下,什么最有效?忘记关闭mySQL连接有什么问题吗?

Appreciate taking your time to answer.

感谢你花时间来回答。

Thank you!

谢谢你!

6 个解决方案

#1


24  

As far as I know, unless you are using persistent connections, your MySQL connection will be closed at the end of the page execution.

据我所知,除非您正在使用持久连接,否则您的MySQL连接将在页面执行结束时关闭。

Therefore, you calling disconnect will add nothing and because you do the lazy connection, may cause a second connection to be created if you or another developer makes a mistake and disconnects at the wrong time.

因此,调用disconnect不会添加任何内容,因为您执行惰性连接,如果您或其他开发人员在错误的时间犯了错误并断开连接,则可能会创建第二个连接。

Given that, I would just allow my connection to close automatically for me. Your pages should be executing quickly, therefore holding the connection for that small amount of time shouldn't cause any problems.

考虑到这一点,我将允许我的连接自动关闭。您的页面应该快速执行,因此保持连接的时间不应该引起任何问题。

#2


5  

I just read this comment on PHP website regarding persistent connection and it might be interesting to know:

我刚刚在PHP网站上读到这篇关于持久连接的评论,可能会很有趣:

Here's a recap of important reasons NOT to use persistent connections:

以下是不使用持久连接的重要原因:

  • When you lock a table, normally it is unlocked when the connection closes, but since persistent connections do not close, any tables you accidentally leave locked will remain locked, and the only way to unlock them is to wait for the connection to timeout or kill the process. The same locking problem occurs with transactions. (See comments below on 23-Apr-2002 & 12-Jul-2003)

    当您锁定一个表时,通常在连接关闭时它是解锁的,但是由于持久连接没有关闭,您意外地保持锁定的任何表都将保持锁定,解锁它们的唯一方法是等待连接超时或终止进程。事务也存在同样的锁定问题。(见以下2003年4月23日-2002年7月12日的评论)

  • Normally temporary tables are dropped when the connection closes, but since persistent connections do not close, temporary tables aren't so temporary. If you do not explicitly drop temporary tables when you are done, that table will already exist for a new client reusing the same connection. The same problem occurs with setting session variables. (See comments below on 19-Nov-2004 & 07-Aug-2006)

    通常,当连接关闭时,会删除临时表,但是由于持久连接不会关闭,所以临时表就不是那么临时的了。如果您在完成时没有显式地删除临时表,那么该表将为新客户机重新使用相同的连接而存在。在设置会话变量时也会出现相同的问题。(见以下2004年11月19日及07年8月7日的评论)

  • If PHP and MySQL are on the same server or local network, the connection time may be negligible, in which case there is no advantage to persistent connections.

    如果PHP和MySQL在同一服务器或本地网络上,连接时间可能可以忽略,在这种情况下,持久连接没有优势。

  • Apache does not work well with persistent connections. When it receives a request from a new client, instead of using one of the available children which already has a persistent connection open, it tends to spawn a new child, which must then open a new database connection. This causes excess processes which are just sleeping, wasting resources, and causing errors when you reach your maximum connections, plus it defeats any benefit of persistent connections. (See comments below on 03-Feb-2004, and the footnote at http://devzone.zend.com/node/view/id/686#fn1)

    Apache不能很好地处理持久连接。当它接收到来自新客户端的请求,而不是使用已经具有持久连接的可用子节点时,它倾向于产生一个新子,它必须打开一个新的数据库连接。这导致了过多的进程,这些进程正在休眠、浪费资源,并在到达最大连接时导致错误,此外,它还会破坏持久连接的任何好处。(参见下面03-Feb-2004的评论,以及http://devzone.zend.com/node/view/id/686#fn1的脚注)

(I was not the one that wrote the text above)

(不是我写的)

#3


5  

Don't bother disconnecting. The cost of checking $_connected before each query combined with the cost of actually calling $db->disconnectFromDB(); to do the closing will end up being more expensive than just letting PHP close the connection when it is finished with each page.

别烦断开。在每个查询之前检查$_connected的成本,以及实际调用$db->disconnectFromDB()的成本;关闭连接要比PHP在完成每个页面时关闭连接花费更多。

Reasoning:

推理:

1: If you leave the connection open till the end of the script:

1:如果你让连接一直打开直到脚本结束:

  • PHP engine loops through internal array of mysql connections
  • PHP引擎循环遍历mysql连接的内部数组
  • PHP engine calls mysql_close() internally for each connection
  • PHP引擎在内部为每个连接调用mysql_close()

2: If you close the connection yourself:

2:如果你自己关闭连接:

  • You have to check the value of $_connected for every single query. This means PHP has to check that the variable $_connected A) exists B) is a boolean and C) is true/false.
  • 您必须检查$_connected for每一个查询的值。这意味着PHP必须检查变量$_connected A)是否存在B)是布尔值,C)是真/假。
  • You have to call your 'disconnect' function, and function calls are one of the more expensive operations in PHP. PHP has to check that your function A) exists, B) is not private/protected and C) that you provided enough arguments to your function. It also has to create a copy of the $connection variable in the new local scope.
  • 您必须调用“断开连接”函数,函数调用是PHP中比较昂贵的操作之一。PHP必须检查你的函数A)存在,B)不是私有的/受保护的,C)你为你的函数提供了足够的参数。它还必须在新的本地范围中创建$connection变量的副本。
  • Then your 'disconnect' function will call mysql_close() which means PHP A) checks that mysql_close() exists and B) that you have provided all needed arguments to mysql_close() and C) that they are the correct type (mysql resource).
  • 然后,“断开”函数将调用mysql_close(),即PHP A)检查mysql_close()是否存在,以及B)是否为mysql_close()和C)提供了所有必需的参数,以确定它们是正确的类型(mysql资源)。

I might not be 100% correct here but I believe the odds are in my favour.

我在这里可能不是百分之百正确,但我相信可能性是对我有利的。

#4


2  

You may want to look at a using persistent connections. Here are two links to help you out

您可能需要查看使用持久连接。这里有两个链接可以帮助你

http://us2.php.net/manual/en/features.persistent-connections.php

http://us2.php.net/manual/en/features.persistent-connections.php

http://us2.php.net/manual/en/function.mysql-pconnect.php

http://us2.php.net/manual/en/function.mysql-pconnect.php

#5


1  

The basic unit of execution presumably is an entire script. What you first of all are wanting to apply resources (i.e. the database) to, efficiently and effectively, is the entirety of a single script.

执行的基本单元大概是一个完整的脚本。首先,您希望将资源(即数据库)应用到、高效和有效地,是单个脚本的全部。

However, PHP, Apache/IIS/whatever, have lives of their own; and they are capable of using the connections you open beyond the life of your script. That's the signficance of persistent (or pooled) connections.

然而,PHP、Apache/IIS/等等,都有自己的生命;并且他们能够使用你在你的脚本生命之外打开的连接。这是持久(或联合)连接的虚构。

Back to your script. It turns out you have a great deal of opportunity to be creative about using that connection during its execution.

回到你的脚本。事实证明,在执行过程中,您有很多机会创造性地使用这种连接。

The typical naive script will tend to hit the connection again and again, picking up locally appropriate scraps of data associated with given objects/modules/selected options. This is where procedural methodology can inflict a penalty on that connection by opening, requesting, receiving, and closing. (Note that any single query will remain alive until it is explicitly closed, or the script ends. Be careful to note that a connection and a query are not the same thing at all. Queries tie up tables; connections tie up ... connections (in most cases mapped to sockets). So you should be conscious of proper economy in the use of both.

典型的原始脚本往往会一次又一次地访问连接,获取与给定对象/模块/选定选项相关的本地适当数据碎片。在这一点上,程序方法可以通过打开、请求、接收和关闭对该连接进行惩罚。(注意,任何查询都将保持活动状态,直到显式关闭,或者脚本结束。请注意,连接和查询根本不是一回事。查询占用表;连接包扎……连接(在大多数情况下映射到套接字)。所以在使用这两种方法时,你应该注意适当的节约。

The most economical strategy with regard to queries is to have as few as possible. I'll often try to construct a more or less complex joined query that brings back a full set of data rather than parceling out the requests in small pieces.

关于查询,最经济的策略是尽可能少地查询。我经常尝试构建一个或多或少复杂的连接查询,它会返回完整的数据集,而不是将请求分成小块。

#6


1  

Using a lazy connection is probably a good idea, since you may not need the database connection at all for some script executions.

使用惰性连接可能是一个好主意,因为对于某些脚本执行,您可能根本不需要数据库连接。

On the other hand, once it's open, leave it open, and either close it explicitly as the script ends, or allow PHP to clean up the connection - having an open connection isn't going to harm anything, and you don't want to incur the unnecessary overhead of checking and re-establishing a connection if you are querying the database a second time.

另一方面,一旦打开,把它打开,或者显式地关闭它的脚本结束时,或允许PHP清理连接——不会伤害任何一个开放的连接,和你不想招致不必要的开销的检查和重建连接如果你第二次查询数据库。

#1


24  

As far as I know, unless you are using persistent connections, your MySQL connection will be closed at the end of the page execution.

据我所知,除非您正在使用持久连接,否则您的MySQL连接将在页面执行结束时关闭。

Therefore, you calling disconnect will add nothing and because you do the lazy connection, may cause a second connection to be created if you or another developer makes a mistake and disconnects at the wrong time.

因此,调用disconnect不会添加任何内容,因为您执行惰性连接,如果您或其他开发人员在错误的时间犯了错误并断开连接,则可能会创建第二个连接。

Given that, I would just allow my connection to close automatically for me. Your pages should be executing quickly, therefore holding the connection for that small amount of time shouldn't cause any problems.

考虑到这一点,我将允许我的连接自动关闭。您的页面应该快速执行,因此保持连接的时间不应该引起任何问题。

#2


5  

I just read this comment on PHP website regarding persistent connection and it might be interesting to know:

我刚刚在PHP网站上读到这篇关于持久连接的评论,可能会很有趣:

Here's a recap of important reasons NOT to use persistent connections:

以下是不使用持久连接的重要原因:

  • When you lock a table, normally it is unlocked when the connection closes, but since persistent connections do not close, any tables you accidentally leave locked will remain locked, and the only way to unlock them is to wait for the connection to timeout or kill the process. The same locking problem occurs with transactions. (See comments below on 23-Apr-2002 & 12-Jul-2003)

    当您锁定一个表时,通常在连接关闭时它是解锁的,但是由于持久连接没有关闭,您意外地保持锁定的任何表都将保持锁定,解锁它们的唯一方法是等待连接超时或终止进程。事务也存在同样的锁定问题。(见以下2003年4月23日-2002年7月12日的评论)

  • Normally temporary tables are dropped when the connection closes, but since persistent connections do not close, temporary tables aren't so temporary. If you do not explicitly drop temporary tables when you are done, that table will already exist for a new client reusing the same connection. The same problem occurs with setting session variables. (See comments below on 19-Nov-2004 & 07-Aug-2006)

    通常,当连接关闭时,会删除临时表,但是由于持久连接不会关闭,所以临时表就不是那么临时的了。如果您在完成时没有显式地删除临时表,那么该表将为新客户机重新使用相同的连接而存在。在设置会话变量时也会出现相同的问题。(见以下2004年11月19日及07年8月7日的评论)

  • If PHP and MySQL are on the same server or local network, the connection time may be negligible, in which case there is no advantage to persistent connections.

    如果PHP和MySQL在同一服务器或本地网络上,连接时间可能可以忽略,在这种情况下,持久连接没有优势。

  • Apache does not work well with persistent connections. When it receives a request from a new client, instead of using one of the available children which already has a persistent connection open, it tends to spawn a new child, which must then open a new database connection. This causes excess processes which are just sleeping, wasting resources, and causing errors when you reach your maximum connections, plus it defeats any benefit of persistent connections. (See comments below on 03-Feb-2004, and the footnote at http://devzone.zend.com/node/view/id/686#fn1)

    Apache不能很好地处理持久连接。当它接收到来自新客户端的请求,而不是使用已经具有持久连接的可用子节点时,它倾向于产生一个新子,它必须打开一个新的数据库连接。这导致了过多的进程,这些进程正在休眠、浪费资源,并在到达最大连接时导致错误,此外,它还会破坏持久连接的任何好处。(参见下面03-Feb-2004的评论,以及http://devzone.zend.com/node/view/id/686#fn1的脚注)

(I was not the one that wrote the text above)

(不是我写的)

#3


5  

Don't bother disconnecting. The cost of checking $_connected before each query combined with the cost of actually calling $db->disconnectFromDB(); to do the closing will end up being more expensive than just letting PHP close the connection when it is finished with each page.

别烦断开。在每个查询之前检查$_connected的成本,以及实际调用$db->disconnectFromDB()的成本;关闭连接要比PHP在完成每个页面时关闭连接花费更多。

Reasoning:

推理:

1: If you leave the connection open till the end of the script:

1:如果你让连接一直打开直到脚本结束:

  • PHP engine loops through internal array of mysql connections
  • PHP引擎循环遍历mysql连接的内部数组
  • PHP engine calls mysql_close() internally for each connection
  • PHP引擎在内部为每个连接调用mysql_close()

2: If you close the connection yourself:

2:如果你自己关闭连接:

  • You have to check the value of $_connected for every single query. This means PHP has to check that the variable $_connected A) exists B) is a boolean and C) is true/false.
  • 您必须检查$_connected for每一个查询的值。这意味着PHP必须检查变量$_connected A)是否存在B)是布尔值,C)是真/假。
  • You have to call your 'disconnect' function, and function calls are one of the more expensive operations in PHP. PHP has to check that your function A) exists, B) is not private/protected and C) that you provided enough arguments to your function. It also has to create a copy of the $connection variable in the new local scope.
  • 您必须调用“断开连接”函数,函数调用是PHP中比较昂贵的操作之一。PHP必须检查你的函数A)存在,B)不是私有的/受保护的,C)你为你的函数提供了足够的参数。它还必须在新的本地范围中创建$connection变量的副本。
  • Then your 'disconnect' function will call mysql_close() which means PHP A) checks that mysql_close() exists and B) that you have provided all needed arguments to mysql_close() and C) that they are the correct type (mysql resource).
  • 然后,“断开”函数将调用mysql_close(),即PHP A)检查mysql_close()是否存在,以及B)是否为mysql_close()和C)提供了所有必需的参数,以确定它们是正确的类型(mysql资源)。

I might not be 100% correct here but I believe the odds are in my favour.

我在这里可能不是百分之百正确,但我相信可能性是对我有利的。

#4


2  

You may want to look at a using persistent connections. Here are two links to help you out

您可能需要查看使用持久连接。这里有两个链接可以帮助你

http://us2.php.net/manual/en/features.persistent-connections.php

http://us2.php.net/manual/en/features.persistent-connections.php

http://us2.php.net/manual/en/function.mysql-pconnect.php

http://us2.php.net/manual/en/function.mysql-pconnect.php

#5


1  

The basic unit of execution presumably is an entire script. What you first of all are wanting to apply resources (i.e. the database) to, efficiently and effectively, is the entirety of a single script.

执行的基本单元大概是一个完整的脚本。首先,您希望将资源(即数据库)应用到、高效和有效地,是单个脚本的全部。

However, PHP, Apache/IIS/whatever, have lives of their own; and they are capable of using the connections you open beyond the life of your script. That's the signficance of persistent (or pooled) connections.

然而,PHP、Apache/IIS/等等,都有自己的生命;并且他们能够使用你在你的脚本生命之外打开的连接。这是持久(或联合)连接的虚构。

Back to your script. It turns out you have a great deal of opportunity to be creative about using that connection during its execution.

回到你的脚本。事实证明,在执行过程中,您有很多机会创造性地使用这种连接。

The typical naive script will tend to hit the connection again and again, picking up locally appropriate scraps of data associated with given objects/modules/selected options. This is where procedural methodology can inflict a penalty on that connection by opening, requesting, receiving, and closing. (Note that any single query will remain alive until it is explicitly closed, or the script ends. Be careful to note that a connection and a query are not the same thing at all. Queries tie up tables; connections tie up ... connections (in most cases mapped to sockets). So you should be conscious of proper economy in the use of both.

典型的原始脚本往往会一次又一次地访问连接,获取与给定对象/模块/选定选项相关的本地适当数据碎片。在这一点上,程序方法可以通过打开、请求、接收和关闭对该连接进行惩罚。(注意,任何查询都将保持活动状态,直到显式关闭,或者脚本结束。请注意,连接和查询根本不是一回事。查询占用表;连接包扎……连接(在大多数情况下映射到套接字)。所以在使用这两种方法时,你应该注意适当的节约。

The most economical strategy with regard to queries is to have as few as possible. I'll often try to construct a more or less complex joined query that brings back a full set of data rather than parceling out the requests in small pieces.

关于查询,最经济的策略是尽可能少地查询。我经常尝试构建一个或多或少复杂的连接查询,它会返回完整的数据集,而不是将请求分成小块。

#6


1  

Using a lazy connection is probably a good idea, since you may not need the database connection at all for some script executions.

使用惰性连接可能是一个好主意,因为对于某些脚本执行,您可能根本不需要数据库连接。

On the other hand, once it's open, leave it open, and either close it explicitly as the script ends, or allow PHP to clean up the connection - having an open connection isn't going to harm anything, and you don't want to incur the unnecessary overhead of checking and re-establishing a connection if you are querying the database a second time.

另一方面,一旦打开,把它打开,或者显式地关闭它的脚本结束时,或允许PHP清理连接——不会伤害任何一个开放的连接,和你不想招致不必要的开销的检查和重建连接如果你第二次查询数据库。