使用“ ORDER BY”,简单的SQL查询将花费10-20倍

时间:2019-01-29 18:36:06

标签: mysql wordpress performance sql-order-by query-optimization

使用“ ORDER BY”,简单的SQL查询需要10到20倍的时间。如何加快速度?

我的第一个查询是:

SELECT * 
FROM wp_usermeta 
WHERE meta_key = 'partner' 
AND meta_value = 1 
ORDER BY user_id DESC
LIMIT 5

需要0.2601秒。经过研究后,我可以对其进行优化,以:

SELECT user_id 
FROM wp_usermeta 
WHERE meta_key = 'partner' 
AND meta_value = '1' 
ORDER BY umeta_id DESC
LIMIT 5

此查询仅需0.1491秒,但仍然太多。如果删除ORDER BY,则只需0.0075秒。

我在Stackoverflow和其他论坛上读了很多书,但没有更好的输出。有人知道吗?

这是标准的WordPress usermeta表。

2 个答案:

答案 0 :(得分:1)

WordPress中的wp_usermeta表是众所周知的,并且在meta_key上具有单列索引。

但是这会选择具有指定键的 all 行,这并不会缩小搜索范围。而且它也无助于排序,因此查询必须做额外的工作才能进行排序:

mysql> explain SELECT *  FROM wp_usermeta WHERE meta_key = 'partner'  AND meta_value = 1  ORDER BY user_id DESC LIMIT 5\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: wp_usermeta
         type: ref
possible_keys: meta_key
          key: meta_key
      key_len: 767
          ref: const
         rows: 1
        Extra: Using where; Using filesort

添加新索引应该会有所帮助:

mysql> alter table wp_usermeta add key (meta_key(191), meta_value(191), user_id);

mysql> explain SELECT *  FROM wp_usermeta WHERE meta_key = 'partner'  AND meta_value = 1  ORDER BY user_id DESC LIMIT 5\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: wp_usermeta
         type: ref
possible_keys: meta_key_2,meta_key
          key: meta_key_2
      key_len: 767
          ref: const
         rows: 1
        Extra: Using where; Using filesort

即使这表明它正在使用新索引(meta_key_2),也无济于事。 key_lenref表示它仅使用索引的第一列。为什么不能同时使用这两列?

因为您的查询将整数值1与字符串列meta_value进行比较。您必须将类似的类型(即字符串'1')与字符串列进行比较:

mysql> explain SELECT *  FROM wp_usermeta WHERE meta_key = 'partner'  AND meta_value = '1'  ORDER BY user_id DESC LIMIT 5\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: wp_usermeta
         type: ref
possible_keys: meta_key_2,meta_key
          key: meta_key_2
      key_len: 1534
          ref: const,const
         rows: 1
        Extra: Using where

现在它可以使用索引中的第二列来搜索值'1',您可以知道,因为key_len: 1534ref: const,const表示它正在使用索引的两列而不是一个列。

然后,优化器意识到它已经按user_id顺序读取了数据,因此不需要排序。 “使用文件排序”消失了。

答案 1 :(得分:0)

WP的“元”表具有无效的架构。但是它们可以解决。在[此处]中,我讨论了一些需要解决的问题。并且我解释了191 kludge,外加5种避免方法。

由于综合索引总是(?)更好,因此我不会涉及“索引合并相交”。