PHP/MySQL 数据库查询的工作原理是什么?

6

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

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

当结果返回时,我假设它保存了所有数据结果,而不是以片段形式返回,并且仅在要求的位置返回,例如 $row->column_name?
或者,即使您只想要 $result 中的一个列,它是否真的会返回每一行数据?
此外,如果我使用 LIMIT 进行分页,即使数据库已更新,它是否仍会保留原始(旧)结果?
4个回答

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)只需要计划一次(至少在它从查询缓存中失效之前)。

我从来没有完全理解参数化查询的工作原理。常规的参数化查询方式是将 SELECT * FROM table WHERE a = :param 与参数一起发送到数据库引擎吗?我认为 :param 将在客户端被替换为一个值。 - We Are All Monica
参数化查询(可能是从客户端库转换为数据库理解的形式)以及参数一起发送到数据库。 - cletus

6

我认为你混淆了两种变量类型,迄今为止还没有真正澄清这一点。

$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知道您只需要某个特定组的行,则通常可以执行重要的优化。


1

第一个问题可以通过阅读资源来回答。

由于您正在选择“*”,因此每个mysql_fetch_object调用都会返回每个列。只需查看print_r($row)即可了解。


1
每次mysql_fetch_object调用都返回每一行吗??你肯定是指每列。 - We Are All Monica

0
简单来说,返回的资源就像是MySQL库与其他数据相关联的ID。我认为它就像你钱包里的身份证,只是一个数字和一些信息,但如果你把它给政府或你的手机公司等,就会关联很多更多的信息。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接