哪一个更快/更高效-大量的小MySQL查询还是一个大的PHP数组?

哪一个更快/更高效-大量的小MySQL查询还是一个大的PHP数组?,php,mysql,arrays,performance,Php,Mysql,Arrays,Performance,我有一个基于PHP/MySQL的web应用程序,它通过一个名为language\u strings的MySQL表(带有string\u id、lang\u id和lang\u text字段)提供国际化支持 当我需要以所选语言显示字符串时,我调用以下函数: 公共函数get\u lang\u string($string\u id,$lang\u id) { $db=新数据库(); $sql=sprintf('SELECT lang_string FROM lang_string,其中lang_id

我有一个基于PHP/MySQL的web应用程序,它通过一个名为
language\u strings
的MySQL表(带有
string\u id
lang\u id
lang\u text
字段)提供国际化支持

当我需要以所选语言显示字符串时,我调用以下函数:

公共函数get\u lang\u string($string\u id,$lang\u id)
{
$db=新数据库();
$sql=sprintf('SELECT lang_string FROM lang_string,其中lang_id IN(1,%s)和string_id=%s按lang_id DESC LIMIT 1'排序,$db->escape($lang_id,'int'),$db->escape($string_id,'int');
$row=$db->query\u first($sql);
返回$row['lang_string'];
}
这工作得很好,但我担心可能会有很多数据库查询正在进行。e、 g.主菜单有5个链接文本,所有链接文本都调用此功能

将所选
lang\u id
的整个
language\u字符串
表结果加载到PHP数组中,然后从函数中调用,会更快吗?这可能是一个巨大的数组,其中大部分是冗余的,但很明显,每个页面加载一个数据库查询,而不是很多


有人能提出另一种更有效的方法吗?

没有不区分大小写的答案。你可以通过一个具体的陈述来看待它。话虽如此,在大多数情况下,在一个查询中获取所有数据、将其弹出到数组或对象中并从那里引用数据会更快

需要注意的是,您是否可以在一个查询中提取所需的所有数据,其速度与运行五个单独的查询一样快。这就是查询本身的性能发挥作用的地方

有时,包含一两个子查询的查询实际上比单独运行几个查询的时间效率要低

我的建议是试验一下。收集一个查询,获取所需的所有数据,查看执行所需的时间。对其他五个查询中的每一个查询计时,看看它们加起来需要多长时间。如果几乎相同,则将输出粘贴到一个数组中,由于不必频繁连接数据库本身,因此效率更高

但是,如果组合查询返回数据所需的时间较长(例如,它可能会导致全表扫描而不是使用索引),那么请坚持使用单个索引


最后,如果你要反复使用相同的数据,那么数组或对象每次都会轻而易举地获胜,因为访问它要比从数据库中获取数据快得多。

同意这里大家所说的。。这都是关于数字的

其他一些提示:

  • 尝试创建一个存储所需最小值的内存阵列。这意味着要消除大部分明显的冗余

  • 在性能关键型环境中,有解决这些问题的标准方法,比如将memcached与mysql结合使用。这有点过头了,但这基本上可以让您分配一些外部内存并将查询缓存在那里。由于您可以选择要分配的内存量,因此可以根据系统的内存量进行规划

  • 只是玩数字游戏。尝试使用单独的查询(这是最简单的方法)并强调PHP脚本(比如从命令行调用数百次)。测量这需要多少时间,看看性能损失到底有多大。。从我个人的经验来看,我通常把所有东西都缓存在内存中,然后有一天当数据变得太大时,我的内存就用完了。然后我将所有内容拆分为单独的查询以节省内存,并看到性能影响一开始并没有那么糟糕:)


  • 在这一点上,我和Fluffeh是一致的:研究您可以使用的其他选项(联接、子查询,确保您的索引反映数据的相关性,但不要过度索引和测试)。很有可能在某个时候会得到一个数组,所以这里有一点性能提示,与您可能期望的相反,比如

    $all = $stmt->fetchAll(PDO::FETCH_ASSOC);
    
    与以下各项相比,内存效率更低:

    $all = array();//or $all = []; in php 5.4
    while($row = $stmt->fetch(PDO::FETCH_ASSOC);
    {
        $all[] = $row['lang_string '];
    }
    

    此外,您还可以在获取数据时检查冗余数据。

    我的答案是在这两者之间做点什么。检索小于特定长度(例如,100个字符)的lang_id的所有字符串。较短的文本字符串比较长的字符串更有可能在多个位置使用。在get_lang_string()中缓存静态关联数组中的项。如果找不到项目,则通过查询检索它。

    好的-我做了一些基准测试,并惊讶地发现将项目放入数组而不是使用单个查询平均要慢10-15%

    我认为这样做的原因是,即使我过滤掉了“不常见”的元素,不可避免地总会有未使用的元素

    对于单独的查询,我只能得到我所需要的,因为查询是如此简单,我认为我最好还是坚持这种方法


    这对我来说是可行的,当然,在其他情况下,单个查询更复杂,我认为将公共数据存储在数组中的方法会更有效。

    我目前正处于我的
    站点/应用程序
    中,我不得不踩刹车,仔细考虑速度。我认为这些速度测试应该考虑服务器上的流量作为一个重要的变量来影响结果。如果将数据放入javascript数据结构并在客户机上进行处理,则处理时间应该更加规则。如果您通过php(例如)通过mysql请求大量数据,这将把需求放在一台机器/服务器上,而不是分散它。随着流量的增长,您必须与许多用户共享服务器资源,我认为