!
也想出现在这里? 联系我们
广告位

WordPress多种分类法混合查询优化方案

我们在使用 WordPress 建站,特别是一些 CMS 类型的站点,多种分类法是常用的,然而 WordPress 在使用多种分类法混合查询的时候,这个查询Y W c J w 5语句就复杂了,在分类和文章数量多了之后,速度就堪忧了,所以这里提一种优化方案供参考。

举例:某个案例中,对于默认的除了的 category 和 post_tag,新增了一个F t I I ^P i ? 2 \ y为 kind 的分类法,注册新分类法的步骤这里就不赘述了,% Y d W s K M l然后我们需要查询出同时归属: 8 9 6 o !于 categoi \ S , } L rryID 为 1,kind 的 ID 为 2 的文章,普c ^ / J f V I ^通的做法:

  1. $args = array(
  2. 'post_type'=>'post',
  3. 'tax_query'=>array(
  4. 'relation'=>'AND',
  5. array(
  6. 'taxonomy'=>'category',
  7. 'field'=&~ S zgt;'term_id',
  8. 'operator'=>'IN',
  9. 'terms'=&v $ 5gt;array(1)
  10. ),
  11. array(
  12. 'taxonomy'L m n v j=&gt. N W Y d;'kind',
  13. 'field'=>'tl h v :erm_id',
  14. 'operator'=&N 7 ! P M 8gt;'IN',
  15. 'terO \ U + G Cms'=>array(2),] S h ]
  16. )
  17. )
  18. );
  19. query_posts($args);v U 7 9 2 ) 4 ` x

就上S % @ H +面这个查询来说,在没有缓存的情况下要执行 3 次数据库: \ 5 i l询,前面两次分别查询对应的分类是否存在,重点是第 3 次文章查询,由于 wordpress 分类和文章的对应关系存储 wp_term_re] f , # [ # J t ^latia | T = ~ monships 表中,每篇I # k B文章对应每一个分类都有一条记录,所以查询文章的时候主要要两次 left join 这个 wp_term_relationships 表,一旦数据量多起来,这样的查询g } 7 w . e { o就比较慢了,附打印出的查询语句如下。

  1. SELECT SQL_CALC_FOUND_ROWS wp_posts.ID FROM wp_pos0 + h A = z R ~ uts+ P k p b z LEFT JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationshipsH | U 8 D . a s p.objecx Z * _ }t_im c O z r T F n Hd) LEFTU [ | 5 f F JOIN wp_t v Eterm_relationships AS tt1 ON (wp_posts.ID = tt1.object_id) WHERE5 D ` 1=1 AND (
  2. wp_term_relat1 V [ionships.term_taxonomy_S % N sid IN (1)
  3. AND
  4. tt1.term_taxonomy_id IN (2)8 Y ! Q S;
  5. ) AND wp_posts.post_type = 'post' AND (wp_posts.post_status = 'publish' OR wp_poq = 0 rsts\ I s Y P $.post_status = 'private') GROUP BY wp_posts.g : n G 3 _ ;ID ORDERu 5 0 5 ? l k % BY wp_posts.pV + , N _ A yost_date DESC LIMIT 0, 10

我的解决方案,在 wp_posts 表中增加一个字段,用来存储器中的一个分类的信息,比如这个案例里面我把 kin\ Q c n : y 4 `d 的 I{ G @ L = - OD 信息冗余存储在 wp_posts 表中,然后将查询条件放到 w% W ! )p_posts 表中,这样就能提速了。

第一步:在启用主题的时候,执行 sql 在 wp_posts 表中增加 kind_id 字段,并加上 InJ M 4 _ E t \dex 索引。(在这个案例中因为客户的分类可以确定是单选,所以 kind_id 字段的类型就直接用 int 了,如果你要保存多个分类 ID,v 6 ) N + % $ Z可以改为 varchar 类型,不过 varcharz L g v 7 6 类型就不别弄索引了)。

  1. //激活主题时执行
  2. function ashu_add_pages() $ - / T @ 7123;
  3. global $pagenow;
  4. if 5 - O l D ~ N040; 'themes.ph ! U ~ + 5 fhp' == $pagenow && isset( $_GET['activated'] ) ){
  5. ashuwp_alter_posts_table();
  6. }
  7. }
  8. add_action( 'load-themes.php', 'ashu_add_pages' );
  9. //修改posts表,增加一列kind_id
  10. function ashuwp_alter_posts_table()&b H N ^ W#123;
  11. global $wpdb;
  12. //判断字段是否已经存在
  13. $sql1 = "Describe {$wd t E z | w 1pdb->posts} `kind_id`";
  14. $kind_id_exist = $wpdb->query($sql1)K Y @;;
  15. if( !$kind_id_exist ){
  16. //新增列
  17. $add_column = "ALTERq l # L M k r TABLE {$wpdb->posts} ADD COLUMN `kindK s *_id` INT(10) DEFAULT NULL";
  18. $wpdb->query($ad- x K + y A ` 1 sd_column);
  19. //添加索引
  20. $add_index = "ALTER T_ v K l E B | _ 1ABLE {$wpdb->posts} ADD INDEX kind_id (`kind_iZ R o h , u x 6 6d`)";
  21. $wpdb-&gB t T R U s 9 }t;query($add_index);
  22. }
  23. }

第二步:发布y U ! P ^ u }文章的时候,将 kind 分类的 ID 信息保存到 wp_posts 表中的 kind_id 字段。这里使用 set_object_terms 钩子_ g f J 6 p,就是在设置分类的时候用,当然为了避免后台多选,这里只保存一个 ID 数据

  1. add_action( 'set_objeX 3 ; T i z 0 L hct_terms', 'ashuwp_add_post_kind_id', 10, 6! A z G041;;
  2. function ashuwp_adE ( # w l . bd_pos% x z l 9 p ^t_kind_id( $object_id, $terms, $tt_ids, $taxonomy, $append = false, $old_tt_x ( I m s F o oids = ap r [ D 1 ? + g rrray() )i 0 x Y R c U3;
  3. global $wpdb;
  4. if( $taxonomy=='kind' ){
  5. $term_id = reset( $tt_ids );
  6. if( $term_id ){
  7. $sql = "UPDATE {$wpdb->posts} SET `kind_id`={$term_id} where `ID`={$object_id}&0 S k l 2 j w ;quot;;
  8. $wpdb->get_results( $sql );
  9. }
  10. }
  11. }

第三步:我f Q F - x C希望在使用 WP_Q^ p 7 Y 1 9uery 查询文章时直接传入 kind_id 参数即可,所以使用 posts_where 钩子,检测t w E h % _ 8 \ `是否有 kind_id 参数,然后拼接查询语句。

  1. function ashuwp_query+ 9 W w \ T 7_posts_w\ S rhere( $wh! - 7 C S ^ / 9 ?ere, $query)P 6 6 3 C ] g23;
  2. global $wpdb;
  3. $qv = $query->query_vars;
  4. isset( $qv['kind_id'] ) AND $kind_id = absint($qv['kind_id']) AND $where .= &quotq Y v * M 7 w u 1; ANR S _ E b V 9D {$wpdb->posts}.kind_id = {$kind_id}";
  5. return $+ h E r Cwhere;
  6. }
  7. add_filter( 'posts_where', 'asG S r 5 Z }huwp_query_posts_where', 10, 2);

第四步:查询文章。最开始那一段查询可m T C ^ p W以直接改成如下代码即可。

  1. $args = array(
  2. 'post_type'=>'post',
  3. 'kind_id'=>2, /G ^ ^ a 6/直接使用kind_id做参数
  4. 'tax_query'=>array(
  5. array(
  6. 'taxonomy'=>'category',
  7. 'field'=>'term_id',
  8. 'operaM T 1 ? S R V s +tor'=>'IN',
  9. 'terms'=>array(1)J ~ S m 0 ^;
  10. 2 @ d M w M m s041;
  11. )
  12. );
  13. qus 9 u ! K z m 2ery_posts($argsd & L041;;

好了,就到这里,这里在下只是提供了一种 WordPreE 5 ` w 8ss 的查询优化方案,可用此方案自行改造其= n ] P #他应用。

给TA打赏
共{{data.count}}人
人已打赏
WordPress教程

WordPress优化多类型分类目录/标签侧栏调用通用代码

2022-10-11 15:48:17

WordPress教程

HTML5代码实现网站侧边抽屉式分享浮动导航

2022-10-12 15:48:11

下载说明

  • 1、微码盒所提供的压缩包若无特别说明,解压密码均为weimahe.com
  • 2、下载后文件若为压缩包格式,请安装7Z软件或者其它压缩软件进行解压;
  • 3、文件比较大的时候,建议使用下载工具进行下载,浏览器下载有时候会自动中断,导致下载错误;
  • 4、资源可能会由于内容问题被和谐,导致下载链接不可用,遇到此问题,请到文章页面进行反馈,以便微码盒及时进行更新;
  • 5、其他下载问题请自行搜索教程,这里不一一讲解。

站长声明

本站大部分下载资源收集于网络,只做学习和交流使用,版权归原作者所有;若为付费资源,请在下载后24小时之内自觉删除;若作商业用途,请到原网站购买;由于未及时购买和付费发生的侵权行为,与本站无关。本站发布的内容若侵犯到您的权益,请联系本站删除,我们将及时处理!
0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索