mysql - 帮助提高查询性能

标签 mysql sql left-join query-optimization query-performance

概述:

我有一个构建查询语句的系统。其中一些必须根据传递到系统中的设置参数将一些表连接到其他表。在对创建的查询运行一些性能测试时,我注意到一些查询正在进行全表扫描,在许多情况下,从我读到的内容来看,这对于大型表来说并不好。

我正在尝试做什么:

1 - Remove the full table scans 
2 - Speed up the Query
3 - Find out if there is a more efficient query I can have the system build instead

查询:

SELECT a.p_id_one, b.p_id_two, b.fk_id_one, c.fk_id_two, d.fk_id_two, 
d.id_three, d.fk_id_one 
FROM ATable a 
LEFT JOIN BTable b ON a.p_id_one = b.fk_id_one 
LEFT JOIN CTable c ON b.p_id_two = c.fk_id_two 
LEFT JOIN DTable d ON b.p_id_two = d.fk_id_two 
WHERE a.p_id_one = 1234567890

The Explain

查询时间

Showing rows 0 - 10 (11 total, Query took 0.0016 seconds.)

当前问题:

1 - 我的系统/DBMS (phpmyadmin) 的查询时间在 0.0013 秒到 0.0017 秒之间。

  • 我做了什么来解决?
    全表扫描或“ALL”类型查询正在表(“BTable”、“DTable”)上运行,因此我尝试在适当的 ID 上使用 FORCE INDEX。 使用 FORCE INDEX 会删除全表扫描,但不会加快速度 表现。 我仔细检查了我的 fk_constraints 和索引关系,以确保我没有遗漏任何内容。到目前为止,一切顺利。

2 - Advisor 显示多个警告,其中一些与全表扫描和索引相关。

问题:

假设所有索引均可用并已创建

1 - 有更好的方法来执行此查询吗?

2 - 有多少连接算过多连接?

3 - 连接可能是问题所在吗?

4 - 问题是否出在 WHERE 子句中?

5 - 我可能错过了哪些优化技术/工具?

6 - 如何让该查询以 0.0008 到 0.0001 之间的速度执行?

如果需要图像和视觉效果来帮助澄清我的情况,请在下面的评论中提问。我感谢任何和所有的帮助。

谢谢=)

最佳答案

“p_id_one”并没有告诉我们太多信息。这是自动增量吗?真实的列名称有时会提供基数和意图的重要线索。正如威廉所说,“这个问题肯定还有更多问题”和“总体问题是什么”。

LEFT——你需要它吗?它阻止某些形式的优化;如果“右”表格行不是可选的,请将其删除。

WHERE a.p_id_one = 1234567890 需要 INDEX(p_id_one)。这已经是主键了吗?在这种情况下,不需要额外的 INDEX。 (请提供SHOW CREATE TABLE。)

这些真的是您正在选择的列/表达式吗?它可以产生影响——尤其是在建议使用“覆盖索引”作为优化时。

请提供 EXPLAIN SELECT ... 的输出(这不是您提供的讨论。)该输出将有助于提供 1:many、基数等线索。

如果这些是FOREIGN KEY,则您已经在 b.fk_id_one、c.fk_id_two、d.fk_id_two 上有索引;所以没有什么可做的了。

对于涉及 4 个表的查询来说,1.6 毫秒是一个绝佳的时间。不要计划显着加快速度。您可能每秒处理数百个连接,执行数千个类似的查询。您还需要更多吗?

你使用的是InnoDB吗?这样更适合并发访问。

您的示例似乎没有任何全表扫描;请提供一个例子。

10 行表上的

ALL 无需担心。对于一百万行的表来说这是一件大事。您的 table 会显着增长吗?在担心 ALL 时,您应该注意这一点:全表扫描有时比使用“完美”索引更快。当估计的行数超过表的大约 20% 时,优化器决定扫描。表扫描非常高效,因为它直接扫描整个表,即使跳过 80% 的行也是如此。使用索引更复杂——扫描索引,但是对于在索引中找到的每一行,需要在数据中查找以找到该行。如果您认为不应该看到ALL,那么可能索引的选择性不强。别担心。

不要使用FORCE INDEX - 尽管它可能有助于查询今天的值,但可能会损害明天的查询。

关于mysql - 帮助提高查询性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34462780/

相关文章:

mysql - 查找常见的匹配 ID

UPDATE 上的 SQL Server 死锁

mysql - SQL : Get Products from a category but also must be in another set of categories

php - 循环通过 MySQL 左加入 php 与 2 个单独的查询

mysql - 根据列值添加列数据?

java - 我如何转义冒号( :) in a mysql query over jdbc that contains a variable assignment?

mysql - 如何消除MySQL中的重复行?

java - MySQL JDBC 连接器转义问题

mysql - Nodejs Mysql 优化查询

php - Docker 服务未链接 - WordPress 未连接到 MySQL