1

嵌套查询而不是将它们分开有什么好处?

我使用 PHP 经常从 MySQL 查询,并希望将它们分开以便更好地组织。例如:

是:

$query = "SELECT words.unique_attribute
          FROM words
          LEFT JOIN adjectives ON adjectives.word_id = words.id
          WHERE adjectives = 'confused'";
return $con->query($query);

比说更快/更好:

$query = "SELECT word_id
          FROM adjectives
          WHERE adjectives = 'confused';";
$id = getID($con->query($query));
$query = "SELECT unique_attribute
          FROM words
          WHERE id = $id;";
return $con->query($query);

第二个选项将为我提供一种创建选择函数的方法,我不必重复如此多的查询字符串代码,但如果进行如此多的额外调用(这些调用可能嵌套非常深)将对性能非常不利,我可能会保留它。或者至少注意一下。

4

2 回答 2

1

Like most questions containing 'faster' or 'better', it's a trade-off and it depends on which part you want to speed up and what your definition of 'better' is.

Compared with the two separate queries, the combined query has the advantages of:

  • speed: you only need to send one query to the database system, the database only needs to parse one query string, only needs to compose one query plan, only needs to push one result back up and through the connection to PHP. The difference (when not executing these queries thousands of times) is very minimal, however.
  • atomicity: the query in two parts may deliver a different result from the combined query if the words table changes between the first and second query (although in this specific example this is probably not a constantly-changing table...)

At the same time the combined query also has the disadvantage of (as you already imply):

  • re-usability: the split queries might come in handy when you can re-use the first one and replace the second one with something that selects a different column from the words table or something from another table entirely. This disadvantage can be mitigated by using something like a query builder (not to be confused with an ORM!) to dynamically compose your queries, adding where clauses and joins as needed. For an example of a query builder, check out Zend\Db\Sql.
  • locking: depending on the storage engine and storage engine version you are using, tables might get locked. Most select statements do not lock tables however, and the InnoDB engine definitely doesn't. Nevertheless, if you are working with an old version of MySQL on the MyISAM storage engine and your tables are under heavy load, this may be a factor. Note that even if the combined statement locks the table, the combined query will offer faster average completion time because it is faster in total while the split queries will offer faster initial response (to the first query) while still needing a higher total time (due to the extra round trips et cetera).
于 2013-10-25T00:37:53.800 回答
1

这取决于这些表的大小以及您要放置负载的位置。如果这些表很大并且看到很多活动,那么具有两个单独查询的第二个版本将最大限度地减少您可能看到的连接结果的锁定时间。然而,如果你有一个强大的数据库服务器和快速的 SSD 存储,你最好避免两次进入数据库的开销。

在所有条件相同的情况下,我可能会选择前者——这是一个数据库问题,所以应该在那里解决。我想这些表不会被特别频繁地写入,所以我会确保有足够的 MySQL 缓存可用并密切关注慢查询日志。

于 2013-10-25T00:24:57.667 回答