在MySQL中编写子查询是一个好的实践吗?

4

我正在为某个项目编写以下子查询:

SELECT count(*) from table1 
WHERE userB='$p' AND userA IN 
  (SELECT userB FROM table1 
   WHERE userA='$row[username]')

我很好奇这是否是在PHP中执行此操作的最佳实践,或者我是否应该采用传统方式先获取子查询结果,然后再计算记录数?

5个回答

18
我好奇在PHP中这是否是最佳实践,或者我应该采用先获取子查询结果然后再计算记录的传统方法?抛开将SQL查询留在PHP或存储过程的争议不谈,尽量减少对数据库的访问是最佳实践。往返数据库需要时间,而分离查询会存在数据在查询之间发生变化的风险。
查询本身能否被优化?在这个例子中,可能是的:
SELECT COUNT(*) 
  FROM TABLE t
  JOIN TABLE t2 ON t2.userB = t.userA
               AND t2.userA = '$row[username]'
 WHERE t.userB = '$p' 

如果您真的想确保查询性能,就需要熟悉生成解释计划并解释输出以调整查询。MySQL的解释计划显示MySQL查询优化器如何决定运行SELECT语句以最佳访问所请求的数据。在MySQL中,您只需在SELECT关键字之前添加关键字explain即可生成解释计划。例如:
EXPLAIN SELECT COUNT(*)
          FROM TABLE t
          JOIN TABLE t2 ON t2.userB = t.userA
                       AND t2.userA = '$row[username]'
         WHERE t.userB = '$p'

可能应该早点提到,但您不想从PHP中运行此内容,因为它不会返回您查询的内容。请使用任何SQL IDE,例如PHPMyAdmin /等等。

我已经有了解释计划,但是它意味着什么?!

MySQL EXPLAIN文档是阅读每个返回列及其所代表的内容的好地方。


1
解释SELECT * FROM OMG Ponies; +1 - Corey Ballou

2
只要子查询不会影响性能,我认为最好坚持使用一个查询。这将最小化你需要编写和维护的代码,这几乎总是一件好事。

1
一般来说,大多数数据库使用左连接(可以将您的查询转换为此)比子查询性能更好。

连接通常很有用,但也有一些注意事项。 - OMG Ponies

1

我同意Ted的观点,左连接会更快,而且更易于阅读。 此外,不要使用count(*),而是使用count(id)


0
值得注意的是,子查询仅适用于 MySql 4.1 及更高版本。 尽管理想情况下,每个人都应该使用 MySql 5,但有些用户被限制在他们提供的主机上(我也遇到过几次这样的问题)。

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