从所有自定义字段搜索非常慢。我需要过滤搜索自定义帖子类型

时间:2015-04-06 01:30:17

标签: php mysql database wordpress wordpress-plugin

我在WP和搜索字段中进行自定义搜索,将在自定义字段,标题和发布内容中搜索任何类型的单词。

事实证明,我的数据库有超过100万个自定义字段行,并希望仅针对特定类型的帖子限制搜索。 我已经在循环中执行此操作以显示结果,但我希望此过滤器是在咨询时进行的,因为页面花费了超过20秒来显示结果。

任何人都可以帮助我吗?在我正在使用的代码下面。

    // SEARCH FROM ALL CUSTOM FIELDS
    $post_ids_meta = $wpdb->get_col( $wpdb->prepare( "
    ALTER TABLE wp_posts ADD INDEX (postmeta)
    SELECT DISTINCT post_id FROM {$wpdb->postmeta}
    WHERE meta_value LIKE '%s'
    ", $keyword ) );

    // SEARCH FOR TITLE AND CONTENT
    $post_ids_post = $wpdb->get_col( $wpdb->prepare( "
    ALTER TABLE wp_post s ADD INDEX (posts);
    SELECT DISTINCT ID FROM {$wpdb->posts}
    WHERE post_title LIKE '%s'
    OR post_content LIKE '%s'
    ", $keyword, $keyword ) );
    $post_ids = array_merge( $post_ids_meta, $post_ids_post );

2 个答案:

答案 0 :(得分:2)

UPDATE:

试试这个。它没有经过测试,但我确信如果你检查并修复它会有效:

// SEARCH IN title, content and meta_value
$post_ids = $wpdb->get_col( $wpdb->prepare( "
    SELECT DISTINCT ID FROM {$wpdb->posts} AS p,
    LEFT JOIN {$wpdb->postmeta} AS m,
    ON m.post_id = p.ID
    WHERE p.post_type = '%s'
    AND (
    post_title LIKE '%%s%'
    OR m.meta_value LIKE '%%s%'
    OR post_content LIKE '%%s%')
", $post_type, $keyword, $keyword, $keyword) );

注意:

  • 假设您已输入$post_type& $keyword。例如:$post_type = "fairs";
  • 我在%s之前和之后添加%以确保它是宽带搜索。
  • 在这种情况下,我使用DISTINCT,因为联合表有重复的ID。对于您第一次查询不需要的先前错误假设,我表示道歉。
  • 速度无法保证,因为您正在对未编入索引的post_content进行广角卡搜索。
  • 您应确保以更快的速度索引meta_value字段。如果你的meta不存储太多文本。

好运!

ORIGINAL:

首先,让我们澄清一下:

  1. 删除这2行,因为它不会有帮助(由于重复调用会使情况变得更糟):

    ALTER TABLE wp_posts ADD INDEX(postmeta)

  2. ALTER TABLE wp_posts ADD INDEX (posts);
    
    1. ID已经不同了。所以它无法帮到你:SELECT DISTINCT ID
    2. 最终查询应如下所示:

      // SEARCH FROM ALL CUSTOM FIELDS
      $post_ids_meta = $wpdb->get_col( $wpdb->prepare( "
      SELECT post_id FROM {$wpdb->postmeta}
      WHERE meta_value LIKE '%s'
      ", $keyword ) );
      
      // SEARCH FOR TITLE AND CONTENT
      $post_ids_post = $wpdb->get_col( $wpdb->prepare( "
      SELECT ID FROM {$wpdb->posts}
      WHERE post_title LIKE '%s'
      OR post_content LIKE '%s' // Remove this will boost performance by 90% because post_content is not indexed
      ", $keyword, $keyword ) );
      $post_ids = array_merge( $post_ids_meta, $post_ids_post );
      

      我建议是使用此插件:https://wordpress.org/plugins/search-everything/

答案 1 :(得分:0)

假设$keyword没有通配符,您可以尝试将此查询表达为:

SELECT ID
FROM {$wpdb->posts}
WHERE post_title LIKE '%s'
UNION
SELECT ID
FROM {$wpdb->posts}
WHERE post_content LIKE '%s';

MySQL可能会想出为此使用索引。您想要的索引是:

create index wp_post_title_id on wp_post(post_title, id);
create index wp_post_content_id on wp_post(post_content, id);

这假定{$wpdb->posts}确实是wp_post