4

有一个SELECT foo, bar, FROM users返回 500 行的查询与同时SELECT foo, bar, FROM users WHERE id = x出现 500 个查询之间是否存在明显的性能差异?

在我正在编写的 PHP 应用程序中,我试图在编写清晰易读的代码段之间进行选择,该代码段将生成大约 500 个 SELECT 语句;或者以一种晦涩、复杂的方式编写它,只使用一个返回 500 行的 SELECT。

我更喜欢使用清晰、可维护的代码的方式,但我担心每个 SELECT 的连接开销会导致性能问题。

背景信息,如果它是相关的:1)这是一个 Drupal 模块,用 PHP 编码 2)有问题的表很少得到 INSERT 和 UPDATE,并且很少被锁定 3)由于与问题

谢谢!

4

3 回答 3

9

做一个大批量的 SELECT 并在应用程序代码中解析结果几乎总是比为一行做大量的 SELECT 快。不过,我建议您同时实现并分析它们。始终努力减少您必须做出的假设的数量。

于 2009-12-05T17:05:28.443 回答
3

我不会过多担心 mysql 查询的连接开销,特别是如果您没有关闭每个查询之间的连接。考虑一下,如果您的查询创建了一个临时表,那么您在查询中花费的时间已经超过了查询的开销。

我个人喜欢执行复杂的 SQL 查询,但我发现表的大小、mysql 查询缓存和需要进行范围检查(甚至针对索引)的查询的查询性能都会产生影响。

我建议这样做:

1)建立简单、正确的基线。我怀疑这是不计其数的查询方法。这没有错,而且很可能是完全正确的。运行几次并观察您的查询缓存和应用程序性能。保持您的应用程序可维护的能力非常重要,特别是如果您与其他代码维护者一起工作。此外,如果您要查询非常大的表,小查询将保持可伸缩性。

2)对复杂查询进行编码。比较结果的准确性,然后比较时间。然后在查询上使用 EXPECT 来查看扫描的行是什么。我经常发现,如果我有一个 JOIN、一个 WHERE x != y 或一个创建临时表的条件,查询性能可能会变得非常糟糕,特别是如果我在一个总是在更新的表中。但是,我还发现复杂查询可能不正确,而且随着应用程序的增长,复杂查询更容易中断。复杂查询通常会扫描更大的行集,通常会创建临时表并调用using where扫描。桌子越大,这些东西就越贵。此外,您可能会考虑复杂查询不适合您团队的优势的团队。

3) 与您的团队分享结果。

复杂查询不太可能命中 mysql 查询缓存,如果它们足够大,就不要缓存它们。(您希望为频繁命中的查询保存 mysql 查询缓存。)此外,必须扫描索引的查询 where 谓词也不会那么好。(x != y, x > y, x < y)。诸如SELECT foo, bar FROM users WHERE foo != 'g' and mumble < '360'最终进行扫描之类的查询。(在这种情况下,查询开销的成本可以忽略不计。)

只需从索引中获取所有值,通常无需创建临时表即可完成小型查询,只要您选择和预测的字段都已编入索引。所以查询性能SELECT foo, bar FROM users WHERE id = x非常好(特别是如果列foobar被索引,又名alter table users add index ix_a ( foo, bar );。)

提高应用程序性能的其他好方法是将这些小查询结果缓存在应用程序中(如果合适),或者执行物化视图查询的批处理作业。此外,请考虑 memcached 或 XCache 中的一些功能。

于 2009-12-06T07:33:26.660 回答
1

似乎您知道 500id值是什么,所以为什么不这样做:

// Assuming you have already validated that this array contains only integers
// so there is not risk of SQl injection

$ids = join(',' $arrayOfIds);

$sql = "SELECT `foo`, `bar` FROM `users` WHERE `id` IN ($ids)";
于 2009-12-05T17:13:10.787 回答