查询有 67156 行的索引 MySQL 表,检查 162880 行,索引不起作用吗?
Posted
技术标签:
【中文标题】查询有 67156 行的索引 MySQL 表,检查 162880 行,索引不起作用吗?【英文标题】:Querying an indexed MySQL table with 67156 Rows, checks 162880 Rows, Does index not work? 【发布时间】:2020-03-22 21:40:38 【问题描述】:我在我的数据库中查询wp_posts
表。
目前的指标如下:
我运行以下查询:
SELECT MIN(post_parent)
FROM wp_posts
WHERE post_type = 'product_variation' and post_parent > 365191;
它检查 162880 行,如下所示:
但是,以下查询仅返回 67156 行。
SELECT COUNT(*)
FROM wp_posts
WHERE post_type = 'product_variation' and post_parent > 365191;
那么为什么我的索引没有像我预期的那样工作?
PS: post_parent 是bigInt
【问题讨论】:
【参考方案1】:您的索引正在“工作”,但对这个查询没有用处。
基本上,索引的一个目的是减少需要读取的数据页数。当查询读取 162,880 行中的 67,156 行时,优化器认为每个数据页都需要读取无论如何。那么,为什么还要使用索引呢。
注意,对于这个查询:
SELECT MIN(post_parent)
FROM wp_posts
WHERE post_type = 'product_variation' and post_parent > 365191;
最佳索引位于wp_posts(post_type, post_parent)
。我猜这个索引实际上会被使用,因为它是查询的覆盖索引。所以读取索引比读取原始数据页更有优势。
【讨论】:
【参考方案2】:您的索引正在“工作”,但它仅部分对此查询有用。
您没有透露type_status_date
索引的确切细节,但根据名称,我假设它按特定顺序索引帖子类型、帖子状态和帖子日期字段。
这意味着type_status_date
只能用于根据帖子类型缩小结果范围,但不能用于查找帖子父级,因为后者字段不是索引的一部分。 mysql 在一个查询中只能对一个表使用一个索引。
如果你执行了一个
SELECT COUNT(*)
FROM wp_posts
WHERE post_type = 'product_variation'
查询,那么计数可能会更接近解释中扫描的行数。
正如 Gordon 解释的那样,在这种情况下,帖子类型、帖子父字段的索引会更有效。
【讨论】:
【参考方案3】:EXPLAIN
中的“行”是一个近似值;有时很遥远。
INDEX(post_type, post_parent)
不仅是“覆盖”(意味着在索引中找到所有必要的列),而且与 MIN()
一起,它只会查看一行来给出答案。
解释将通过说“使用索引”(而不是“使用索引条件”)来表示“覆盖”。
EXPLAIN
并不总是降低“行”以解释 LIMIT
、MIN
等。所以,同样,你不能总是相信它。请参阅此以获得准确的计数:http://mysql.rjweb.org/doc.php/index_cookbook_mysql#handler_counts
【讨论】:
以上是关于查询有 67156 行的索引 MySQL 表,检查 162880 行,索引不起作用吗?的主要内容,如果未能解决你的问题,请参考以下文章
如何在不使用索引检查 mysql 表中的 100000 条记录等所有行的情况下获得一行? [关闭]