get_option()vs get_theme_mod():为什么慢一点?


17

我已经在我的get_theme_mod()各种项目中使用了一段时间。我决定在WordPress v3.4中利用主题自定义API,因为我觉得这是我的客户不可或缺的工具。

一段时间后,我开始注意到我的网站感觉比平时慢了很多,尤其是Customizer花费了很长的时间来加载。通过大量的试验和错误我的调查过程中,我决定尝试切换出type注册我的设置(即当$wp_customize->add_setting()从)theme_modoption

完成此操作并换掉所有对的get_theme_mod()调用后get_option(),我注意到使用后一种设置的速度大大提高,这与前端(尤其是后端的Customizer)相比有所提高。我一直在研究WordPress核心,以试图找出答案,但似乎无法识别这种情况下的特殊问题。

社区可能对get_option()执行速度要快得多的任何见解都get_theme_mod()将不胜感激。


1
如果你把一看/wp-includes,在option.php那里get_option()被定义,并在theme.php那里get_theme_mod()被定义,你可以看到,后者实际上调用get_option()本身,作为它的一个扩展,它也适用于任何必要的过滤器。可以解释为什么它变慢了。
乔迪·天堂

1
乔迪,我以为是我自己,但是感觉像是简单地引用get_option()和应用一些过滤器并不能使它的速度变慢。当然是一个很好的起点,但是我想知道这里是否还有其他内容。
ntg2 2014年

3
那里没有任何速度差异的原因,所以我怀疑其他原因导致了您的感知差异。主题模块本身存储为选项。
奥托

在获取单个mod时,序列化/非序列化过程可能以某种方式参与其中吗?我很好奇,是否可能需要额外的提取mod的工作,而不是简单地获取选项而不需要这样做而导致的麻烦。使得当从改变get_theme_mod()get_option()所有项目的速度平均增加了一倍双方的前端,并在定制。这是唯一旨在将其与其他副作用区分开的更改。
ntg2 2014年

Answers:


19

是的,theme_mod函数的响应速度会变慢,但不会明显变慢,其好处大于差异。

主题模块存储为选项。因此,从本质上讲,theme_mod函数是options函数的包装器。

首先,要了解theme_mod设置是作为数组存储在单个选项中的,该选项键入特定的主题名称。因此,如果我这样做:

set_theme_mod('aaa',123);
set_theme_mod('bbb',456);

然后,我实际上从数据库中得到的是一个名为theme_mods_themename的选项行,其中包含一个序列化数组,其中包含('aaa'=> 123,'bbb'=> 456)。

现在,get_theme_mod速度会变慢,因为它实际上正在get_option拨打两个电话。首先,它获得主题的名称。然后,它获得theme_mods_themename选项。因此,有50%的速度损失。剩下的工作大部分都在过滤器中,因为有一个额外的过滤器调用,但是除非您对该过滤器有任何要求,否则这是微不足道的。

请注意,选项系统将检索到的数据存储在对象高速缓存中,因此此处不会进行多个数据库调用。只有首次使用会导致数据库命中。

这样做set_theme_mod会稍慢一些,因为它会调用这两个相同的get选项,然后再次get_option调用以再次获取主题名称,然后update_option使用现在更改的全套选项。这会导致数据库更新,并且它发送大量数据的事实确实可能导致显着的速度下降。更新几个字节比更新较大的行更快。但通常不会如您所愿。除非您有很多设置...

当然,主题mod函数可能应该从总体上进行优化,但是由于子主题,您仍然应该使用它们而不是get_option等。

直接使用选项行的问题在于,您直接使用它们并为设置使用特定的键名。

如果我有一个名为“ AAA”的主题,并且将其子主题为“ BBB”供其他站点使用,那么我的“ AAA”主题可能会使用一个名为“ example”的选项。当我更新一个站点并更新了我的选项时,该选项现在将应用于我的子主题。如果我不想这样做怎么办?如果我希望子主题使用一组不同的选项设置怎么办?

通过将主题的实际名称(而不是硬编码值)作为键的一部分,主题模块可以确保站点上的每个“主题”都使用自己的一套设置。我可以来回切换,并且设置不会在它们之间转移,它们仍然是我的设置方式。更简单,更明显,更直观。

而且,如果将来有一些核心更改或插件修改了theme_mods的工作方式,那么您将无需任何更改即可自动获得好处。包装器总是会变慢,这是不可避免的,这是包装器的本质。但是,您仍在编写PHP代码,而不是机器语言。我们使用这样的包装器来简化事情并分离功能。主题无需了解或关心其选项如何存储在数据库中或命名如何工作。theme_mod函数提供了更简洁的解决方案。


3

get_theme_mod只是一个包装get_option。从理论上讲,由于它是抽象的另一层,因此它的工作速度较慢,但​​实际上,差异不应大到足以引起人类注意。

如果您在theme_mod挂钩上挂了一些慢代码,则可能导致实际速度差异。


1

定制器中可能会发生什么吗?我在这里看到与OP相同的东西。

我可以确认,使用大约30个选项时,我的Customizer加载时间从3s左右下降到get_option了切换到.5s左右get_theme_mod

直接调用方法,我看到2ms的差异。

检测结果https://gist.github.com/anonymous/d98a46d00d52d40e7dec

直接比较API时可能不会引起注意,但是在Customizer中必须使用它们。


1

您可以测试的时间get_option使用此代码(放(100次迭代),functions.php或某处):

add_action('wp','My_Test');
function My_Test(){
    var_dump(microtime(true));
    for ($i=1; $i<100; $i++) { get_option('blogdescription'); }
    var_dump(microtime(true));
    for ($i=1; $i<100; $i++) { get_theme_mod('blogdescription'); }
    var_dump(microtime(true));
    exit;
}   




另一个想法

我不知道这是否有所作为(也许Wordpress开发人员会更好地了解它),但是我认为,如果一个网站的流量很高,并且在每个页面加载时,它都需要获得数百个选项,那么如果我加入有很多选择get_option吗?像这样:

update_option('my_extra_optss',  array(
      'myNAME' => 'George',
      'myAGE'  => 43 ));

然后 :

$x = get_option('my_extra_optss');
$x['myNAME'];
$x['myAGE'];
................

这会使网站更快吗?


2
这正是get_theme_mod已经完成的工作。所有主题模块都已加入一个选项。每当您调用get_theme_mod时,它将第一次进行两次数据库调用,之后进行零次数据库调用。
奥托(Otto)

0

TL; DR:如果您是主题开发人员,则应使用get_theme_mod

完整答案:

如果您有100个get_option调用,它将对您的数据库进行100个查询。

如果您有100次get_theme_mod调用,则只需对数据库查询1次。

为什么?因为所有主题mod都存储在单个数据库行中,并且只能被调用,而每个选项都是一行,并且100次get_option调用将导致100次数据库查询,当然,这会使您的网站变慢。

如果您的主题有很多选择,请使用get_theme_mod将大大减少您查询数据库的次数。

您可以通过查询监视器插件检查性能和查询数量

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.