PHP/MySQL数据库查询如何正常工作?

net*_*rox 5 php mysql database

我经常使用MySQL,但我总是想知道它是如何工作的 - 当我得到一个肯定的结果时,数据存储在哪里?例如,我这样写:

$sql = "SELECT * FROM TABLE"; 
$result = mysql_query($sql);
while ($row = mysql_fetch_object($result)) {
    echo $row->column_name;
}
Run Code Online (Sandbox Code Playgroud)

返回结果时,我假设它保存所有数据结果,或者它是否在片段中返回,只返回它所要求的位置,如$ row-> column_name?

或者,即使您只想在$ result中使用一列,它是否真的会返回每一行数据?

此外,如果我使用LIMIT进行分页,即使数据库已更新,它是否仍保留原始(旧)结果?

cle*_*tus 9

细节是依赖于实现的,但一般来说,结果是缓冲的.对数据库执行查询将返回一些结果集.如果它足够小,所有结果可能会在初始调用时返回,或者某些结果可能会在迭代结果对象时返回更多结果.

以这种方式思考序列:

  1. 您打开与数据库的连接;
  2. 可能有第二次调用选择数据库,或者它可能作为(1)的一部分完成;
  3. 该认证和连接步骤(至少)一次往返服务器(忽略持久连接);
  4. 您在客户端上执行查询;
  5. 该查询被发送到服务器;
  6. 服务器必须确定如何执行查询;
  7. 如果服务器先前已执行查询,则执行计划可能仍在查询缓存中.如果不是,则必须创建新计划;
  8. 服务器执行给定的查询并将结果返回给客户端;
  9. 该结果将包含一些依赖于实现的行缓冲区.它可能是100行或更多或更少.每行返回所有列;
  10. 当您最终获取更多行时,客户端将向服务器请求更多行.这可能是在客户端耗尽或者可能是先发制人的情况下.这又是依赖于实现的.

所有这一切的想法是尽量减少到服务器的往返,而不会发回太多不必要的数据,这就是为什么如果你要求一百万行,你不会立刻得到它们.

LIMIT子句 - 或实际上的任何子句 - 将修改结果集.

最后,(7),因为是重要的SELECT * FROM table WHERE a = 'foo'SELECT * FROM table WHERE a = 'bar'是两个不同的查询只要数据库优化而言所以执行计划必须为每个单独确定.但是SELECT * FROM table WHERE a = :param具有不同参数的参数化查询()是一个查询,并且只需要计划一次(至少直到它超出查询缓存).


jny*_*len 7

我认为你混淆了你正在处理的两种类型的变量,到目前为止,这两种变量都没有真正澄清.

$result是一个MySQL结果对象.它不"包含任何行".当你说$result = mysql_query($sql),MySQL执行查询,并知道哪些行将匹配,但数据尚未转移到PHP端. $result可以被认为是指向您要求MySQL执行的查询的指针.

当你说$row = mysql_fetch_object($result),那是PHP的MySQL接口为你检索一行的时候.只放入该行$row(作为一个普通的旧PHP对象,但您可以使用不同的获取函数来请求每行中的关联数组或特定列.)

行可以缓存,期望您将在紧密循环中检索所有行(通常是这种情况),但通常,当您使用其中一个mysql_fetch_*函数请求行时,将检索行.

如果您只想要数据库中的一列,那么您应该这样做SELECT that_column FROM ....LIMIT尽可能使用子句也是一个好主意,因为如果MySQL知道您只需要某组行,则通常可以执行重要的优化.