一个SELECT foo, bar, FROM users
查询返回500行,500个SELECT foo, bar, FROM users WHERE id = x
查询是否同时出现,是否存在明显的性能差异?
在我正在编写的PHP应用程序中,我正在尝试在编写清晰,可读的代码段之间进行选择,这将产生大约500个SELECT语句;或者以一种模糊,复杂的方式编写它,只使用一个返回500行的SELECT。
我更喜欢使用清晰,可维护代码的方式,但我担心每个SELECT的连接开销都会导致性能问题。
背景信息,如果相关: 1)这是一个用PHP编码的Drupal模块 2)有问题的表获得很少的INSERT和UPDATE,很少被锁定 3)由于与问题无关的原因而无法使用SQL JOIN
谢谢!
答案 0 :(得分:9)
执行一个大批量SELECT并在应用程序代码中解析结果几乎总是比在一行中执行大量SELECT更快。不过,我建议你实现它们并对它们进行分析。始终努力减少您必须做出的假设数量。
答案 1 :(得分:3)
我不会太担心mysql查询的连接开销,特别是如果你没有关闭每个查询之间的连接。考虑一下,如果您的查询创建了一个临时表,那么您在查询中花费的时间已经超过了查询的开销。
我个人喜欢做复杂的SQL查询,但我发现表的大小,mysql查询缓存和查询需要进行范围检查(甚至是索引)的查询性能都会产生影响。< / p>
我建议:
1)建立简单,正确的基线。我怀疑这是一种极好的查询方法。这没有错,很可能是正确的。运行几次,观察您的查询缓存和应用程序性能。保持应用程序可维护性的能力非常重要,特别是如果您与其他代码维护人员一起工作。此外,如果您要查询非常大的表,小查询将保持可伸缩性。
2)对复杂查询进行编码。比较结果的准确性,然后比较时间。然后在查询上使用EXPECT以查看扫描的行。我经常发现,如果我有一个JOIN,或一个WHERE x!= y,或者创建一个临时表的条件,查询性能可能会变得非常糟糕,特别是如果我在一个总是得到更新的表中。但是,我还发现复杂的查询可能不正确,而且随着应用程序的增长,复杂的查询也会更容易破解。复杂查询通常会扫描较大的行集,通常会创建临时表并调用using where
次扫描。桌子越大,这些越贵。此外,您可能需要考虑团队因素,因为复杂的查询不适合您团队的优势。
3)与您的团队分享结果。
复杂查询不太可能命中mysql查询缓存,如果它们足够大,请不要缓存它们。 (您希望为经常命中的查询保存mysql查询缓存。)此外,查询必须扫描索引的谓词也不会这样做。 (x!= y,x> y,x
通常只需要从索引中获取所有值来创建小型查询,而无需创建临时表,只要您选择和预测的字段被编入索引即可。因此,SELECT foo, bar FROM users WHERE id = x
的查询效果非常好(特别是如果列foo
和bar
被编入索引,例如alter table users add index ix_a ( foo, bar );
。)
提高应用程序性能的其他好方法是在应用程序中缓存这些小查询结果(如果适用),或者执行物化视图查询的批处理作业。另外,请考虑在XCache中找到memcached或某些功能。
答案 2 :(得分:1)
您似乎知道500 id
值是什么,所以为什么不这样做:
// 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)";