使用“ORDER BY”的简单 SQL 查询需要多 10-20 倍
Posted
技术标签:
【中文标题】使用“ORDER BY”的简单 SQL 查询需要多 10-20 倍【英文标题】:Simple SQL Query takes 10-20 times more with "ORDER BY" 【发布时间】:2019-06-22 23:10:30 【问题描述】:使用“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 秒。
我在 *** 和其他论坛上阅读了很多内容,但我无法获得更好的输出。有人有想法吗?
这是一个标准的 WordPress 用户元表。
【问题讨论】:
与所有相关表的 SHOW CREATE TABLE 语句一样,关于查询性能的问题总是需要对给定查询的 EXPLAIN 是的,您应该始终在查询优化问题中包含表定义,但wp_usermeta
在 WordPress 数据库中是一个非常容易识别的表。
@billkarwin 这不是重点
【参考方案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_len
和 ref
表示它只使用索引的第一列。为什么不能同时使用两列?
因为您的查询将整数值 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: 1534
和ref: const,const
表明它使用索引的两列而不是一列。
然后优化器意识到它已经按照user_id
的顺序读取数据,所以不需要排序。 “使用文件排序”消失了。
【讨论】:
在大多数情况下,前缀索引不起作用。不查看第一个前缀之后的内容。【参考方案2】:WP 的“元”表的架构效率低下。但它们可以修复。在 [here] 中,我讨论了一些需要修复的问题。我解释了 191 个杂物,以及 5 个避免它的选项。
而且我没有进入“索引合并相交”,因为复合索引总是(?)更好。
【讨论】:
以上是关于使用“ORDER BY”的简单 SQL 查询需要多 10-20 倍的主要内容,如果未能解决你的问题,请参考以下文章