如何在 PHP/MYSQL 中将两个 mysql 查询作为一个执行?
Posted
技术标签:
【中文标题】如何在 PHP/MYSQL 中将两个 mysql 查询作为一个执行?【英文标题】:How to execute two mysql queries as one in PHP/MYSQL? 【发布时间】:2010-10-22 14:13:57 【问题描述】:我有两个查询,如下:
SELECT SQL_CALC_FOUND_ROWS Id, Name FROM my_table WHERE Name LIKE '%prashant%' LIMIT 0, 10;
SELECT FOUND_ROWS();
我想一次性执行这两个查询。
$result = mysql_query($query);
然后告诉我如何处理单独设置的每个表。实际上在 ASP.NET 中,我们使用数据集来处理两个查询
ds.Tables[0];
ds.Tables[1]; .. etc
如何使用 php/MYSQL 做同样的事情?
【问题讨论】:
这是可能的(参见***.com/a/28984274/632951)使用CLIENT_MULTI_STATEMENTS
标志。
【参考方案1】:
像这样:
$result1 = mysql_query($query1);
$result2 = mysql_query($query2);
// do something with the 2 result sets...
if ($result1)
mysql_free_result($result1);
if ($result2)
mysql_free_result($result2);
【讨论】:
他不想避免两次执行mysql_query吗? 是的,我想避免两次 mysql 查询。在@Jon Benedicto 的回答中,他正在执行两个查询。 :( 我刚刚发布了另一个答案,展示了如何使用 MySQLi 一次性执行两个查询。【参考方案2】:它在 PHP 网站上说 multiple queries are NOT permitted(编辑:这仅适用于 mysql 扩展。mysqli 和 PDO 允许多个查询) .所以你不能在 PHP 中做到这一点,但是,为什么你不能在另一个 mysql_query 调用中执行该查询(如 Jon 的示例)?如果您使用相同的连接,它仍然应该给您正确的结果。此外,mysql_num_rows 也可能有所帮助。
【讨论】:
这仅适用于 mysql 扩展。 mysqli 和 PDO 允许多个查询。【参考方案3】:你不能使用SQL_CALC_FOUND_ROWS
。
通过 FOUND_ROWS() 可用的行数是暂时的,并且不打算在 SELECT SQL_CALC_FOUND_ROWS 语句之后的语句之后可用。
正如有人在您之前的问题中指出的那样,使用 SQL_CALC_FOUND_ROWS
通常比仅计数要慢。
也许你最好把它当作子查询来做:
SELECT
(select count(*) from my_table WHERE Name LIKE '%prashant%')
as total_rows,
Id, Name FROM my_table WHERE Name LIKE '%prashant%' LIMIT 0, 10;
【讨论】:
SQL_CALC_FOUND_ROWS 较慢,但在dev.mysql.com/doc/refman/5.0/en/… 链接我发现“但是,这比没有限制再次运行查询要快,因为不需要将结果集发送到客户端。” ?? 但不是在这种情况下,因为查询不能使用索引。 SQL_CALC_FOUND_ROWS 将导致一次表扫描,而您的子查询将导致两次,因此速度要慢得多。另外,您忘记在 total_rows 后面加一个逗号。 是的,好吧,您不会在没有限制的情况下再次运行查询。您正在运行一个计数(*),它发送一行。真的,Emil H 有一个很好的观点——它是对可疑值的微优化。要么运行两个查询,要么如果你绝对必须这样做,就像我解释的那样作为子查询来做。 (Emil H,感谢您指出缺少逗号。)【参考方案4】:更新:显然可以通过将标志传递给mysql_connect()
。见Executing multiple SQL queries in one statement with PHP 不过,任何当前的读者都应该避免使用mysql_
-class 函数,而更喜欢 PDO。
在 PHP 中使用常规的 mysql-api 无法做到这一点。只需执行两个查询。第二个将如此之快,以至于无关紧要。这是微优化的典型例子。不用担心。
为了记录,可以使用 mysqli 和 mysqli_multi_query-function 来完成。
【讨论】:
我主要关心性能,如果我们两次访问数据库,我认为性能会下降。 如果您不相信,请做一个基准测试。执行 SELECT FOUND_ROWS() 查询并检索结果所需的时间可以忽略不计。你已经有了连接,结果集非常小(只有一个整数)。 顺便说一句,如果您担心性能,您应该花时间尝试摆脱 LIKE '%prashant%' 语句。这可能是一个真正的性能问题。根据经验:大多数 php 应用程序的瓶颈根本不在 php 中,而在数据库中。如果您想花时间优化您的应用程序,请花时间检查您的索引并解释您的查询。 我的第一个查询是插入,第二个是获取第一个的 ID。运行到 php 执行是没有问题的,因为记录插入到表中的速度非常快。【参考方案5】:如果您不想执行两次查询,则必须使用 MySQLi 扩展:
if (mysqli_multi_query($link, $query))
$result1 = mysqli_store_result($link);
$result2 = null;
if (mysqli_more_results($link))
mysqli_next_result($link);
$result2 = mysqli_store_result($link);
// do something with both result sets.
if ($result1)
mysqli_free_result($result1);
if ($result2)
mysqli_free_result($result2);
【讨论】:
【参考方案6】:你必须使用 MySQLi,下面的代码运行良好
<?php
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");
/* check connection */
if (mysqli_connect_errno())
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
$query = "SELECT CURRENT_USER();";
$query .= "SELECT Name FROM City ORDER BY ID LIMIT 20, 5";
/* execute multi query */
if ($mysqli->multi_query($query))
do
/* store first result set */
if ($result = $mysqli->store_result())
while ($row = $result->fetch_row())
printf("%s\n", $row[0]);
$result->free();
/* print divider */
if ($mysqli->more_results())
printf("-----------------\n");
while ($mysqli->next_result());
/* close connection */
$mysqli->close();
?>
【讨论】:
【参考方案7】:正如其他人所回答的,mysqli API 可以使用 msyqli_multi_query() 函数执行多查询。
不管怎样,PDO 默认支持多查询,您可以迭代多个查询的多个结果集:
$stmt = $dbh->prepare("
select sql_calc_found_rows * from foo limit 1 ;
select found_rows()");
$stmt->execute();
do
while ($row = $stmt->fetch())
print_r($row);
while ($stmt->nextRowset());
但是,出于安全原因,多查询被广泛认为是一个坏主意。如果您对如何构造查询字符串不小心,您实际上可以得到classic "Little Bobby Tables" XKCD cartoon 中显示的确切类型的 SQL 注入漏洞。使用限制您进行单一查询的 API 时,这是不可能发生的。
【讨论】:
【参考方案8】:是的,它可以不使用 MySQLi 扩展。
只需在mysql_connect
的第五个参数中使用CLIENT_MULTI_STATEMENTS
。
更多信息请参考Husni's post下方的cmets。
【讨论】:
以上是关于如何在 PHP/MYSQL 中将两个 mysql 查询作为一个执行?的主要内容,如果未能解决你的问题,请参考以下文章
试图在php MYSQL中将数据从一个表插入另一个表[关闭]
如何使用 datepicker、ajax、php、mysql 在两个日期之间生成报告?
如何使用会话ID从php mysql中的两个或多个表中获取值