我在运行mysql查询时遇到以下问题:查询速度非常慢,当我使用explain时,查询键为null,但可能的\u键可用,并且顺序正确,我还尝试为每行添加独立索引,但键仍然为null。您可以在这里看到表、索引和mysql解释:https://snag.gy/vcchl6.jpg
gcxthw6b1#
猜测:大多数行都是“project”和“lang”的。优化器不了解这一事实,因此它采用显然是最好的索引:
(id_project, id_lang)
这一个同样好: (id_lang, id_project) .不公平。。。这个 EXPLAIN 提到名为id\u project和id\u lang的索引(不有用),但索引列表显示了一个复合索引 t1(id_project, id_lang) (有用)。然后,正如willem所建议的,它必须在索引和表之间反弹。通常(也就是说,当它有足够的统计信息时),优化器会说“哦,超过20%的表被引用了;让我们忽略任何索引。”您可以做的事情:去掉那个索引。改变 * 添加到所需列的列表中。特别是,如果你避开3 TEXT 列,两个优化启动。或者,任何永远不会超过255个字符的字符都可以更改为 VARCHAR(255) .使用其他一些过滤、排序、限制等。如果这是一个web应用程序,您真的想获得~534行吗?
(id_lang, id_project)
EXPLAIN
t1(id_project, id_lang)
*
TEXT
VARCHAR(255)
ubbxdtey2#
优化器可能刚刚决定没有理由使用索引。既然你用的是 SELECT * 这意味着如果它使用索引,那么它必须使用索引中的主键,然后返回并从聚集索引中查找所有必要的数据。这被称为双重查找,通常对性能不利。由于这个表中的记录太少,优化器可能决定可以轻松地进行一次完整的表扫描,从而更快地得到结果。简而言之,这是预期的行为。如果你想的话 SELECT 只是一些列,将它们添加到 t1 索引,然后 SELECT 只有你需要的列 WHERE 条款。它应该使用索引。当您的表增大时,一旦它估计双重查找比全表扫描便宜,它也可能开始使用索引。
SELECT *
SELECT
t1
WHERE
2条答案
按热度按时间gcxthw6b1#
猜测:大多数行都是“project”和“lang”的。
优化器不了解这一事实,因此它采用显然是最好的索引:
这一个同样好:
(id_lang, id_project)
.不公平。。。这个
EXPLAIN
提到名为id\u project和id\u lang的索引(不有用),但索引列表显示了一个复合索引t1(id_project, id_lang)
(有用)。然后,正如willem所建议的,它必须在索引和表之间反弹。通常(也就是说,当它有足够的统计信息时),优化器会说“哦,超过20%的表被引用了;让我们忽略任何索引。”
您可以做的事情:
去掉那个索引。
改变
*
添加到所需列的列表中。特别是,如果你避开3TEXT
列,两个优化启动。或者,任何永远不会超过255个字符的字符都可以更改为VARCHAR(255)
.使用其他一些过滤、排序、限制等。如果这是一个web应用程序,您真的想获得~534行吗?
ubbxdtey2#
优化器可能刚刚决定没有理由使用索引。
既然你用的是
SELECT *
这意味着如果它使用索引,那么它必须使用索引中的主键,然后返回并从聚集索引中查找所有必要的数据。这被称为双重查找,通常对性能不利。由于这个表中的记录太少,优化器可能决定可以轻松地进行一次完整的表扫描,从而更快地得到结果。简而言之,这是预期的行为。
如果你想的话
SELECT
只是一些列,将它们添加到t1
索引,然后SELECT
只有你需要的列WHERE
条款。它应该使用索引。当您的表增大时,一旦它估计双重查找比全表扫描便宜,它也可能开始使用索引。