【问题标题】:MySQL Query Taking 5 Minutes to ExecuteMySQL 查询需要 5 分钟才能执行
【发布时间】:2018-02-13 21:01:39
【问题描述】:

我是 MySQL 的新手,我第一次尝试使用 LEFT Joins。虽然返回的结果是预期的结果,但查询花费的时间太长了。

我有 3 个要加入的表,当我单独运行查询时,数据会在 0.0002 秒内返回。使用连接查询最多需要 300 秒。

evmbd 有 6012 行需要返回,我只想将 xlba 和 3pla 表中的一列加入到 naa 上

我一直在阅读有关优化 LEFT JOIN 查询的内容,并在 naa 列的所有 3 个表上添加了 INDEX。

SELECT e.cluster,e.vm,e.TotalCapacityGB,e.naa,p.array,x.array
FROM evmbd AS e
LEFT JOIN xlba AS x ON x.naa like replace(e.naa,'naa.','') AND x.date = (select max(date) from xlba ) 
LEFT JOIN 3pla AS p ON p.naa = replace(e.naa,'naa.','') AND p.date = (select max(date) from 3pla )
WHERE e.date = (select max(date) from evmbd)  
GROUP BY e.cluster, e.vm 
ORDER BY e.cluster, e.vm

任何帮助以及有关高级查询的任何文档都会令人惊叹

【问题讨论】:

  • uuuu baby....subselect 在哪里,join 不是按键而是like,实际上不需要是like,因为没有% ,也在连接条件中进行子选择...伙计,你是不是故意让它变慢?!
  • 哈哈哈@TuncayGöncüoğlu nahhh 我只是不知道我在做什么:(
  • @TuncayGöncüoğlu 之类的东西是我一直在做的测试遗留下来的,它在那里运行缓慢。这个查询我应该看什么?
  • 我在下面支持 Rodrigo A. 的回答。他有正确的想法。但是,最重要的是,我会查看您的 3plaxlba 表结构,看看是否可以通过整数键字段而不是字符串搜索加上日期来完成连接。
  • uuuu -- 我们也不知道你在做什么。请尝试描述查询需要做什么。以及naaarray 中有哪些数据。同时提供SHOW CREATE TABLE

标签: mysql performance left-join query-optimization


【解决方案1】:

我不知道你的桌子,但也许这会有所帮助:

DECLARE @MAX_XLBA DATETIME
DECLARE @MAX_3PLA DATETIME
DECLARE @MAX_EVMBD DATETIME

SET @MAX_XLBA = (select max(date) from xlba)
SET @MAX_3PLA = (select max(date) from 3pla)
SET @MAX_EVMBD = (select max(date) from evmbd)

SELECT e.cluster,e.vm,e.TotalCapacityGB,e.naa,p.array,x.array
FROM evmbd AS e
LEFT JOIN xlba AS x ON x.naa = LTRIM(RTRIM(SUBSTRING(e.naa,4,15))) AND x.date = @MAX_XLBA
LEFT JOIN 3pla AS p ON p.naa = LTRIM(RTRIM(SUBSTRING(e.naa,4,15))) AND p.date = @MAX_3PLA
WHERE e.date = @MAX_EVMBD

如果在查询运行时未计算日期,则性能可能会更好。你正在做的替换也是如此。

问候

【讨论】:

    【解决方案2】:

    对于数据量巨大的项目,我在 SQLite 中遇到了同样的问题。太多的连接会大大降低程序的速度。在那里,我使用了以下解决方案:

  • 1。代码中有 2 个左连接,请保留最有效的一个。另一个你可以在得到结果后在内存中计算。
  • 2。在临时表中创建一个子集。然后计算另一个连接。
  • 【讨论】:

    • downvoted:a)它不是 sqlite,它是 mysql,如标签中所述。 b) 建议 1 是不必要的。 c) 建议 2:见前一点。 d) 建议 3 应该完全避免,从长远来看,数据库一致性确实是一个更令人头疼的问题。 e) 建议 4 不适用。好吧,mysql 也有缓冲区设置,但默认值通常没问题。 f) 不要对任何需要并发访问、事务、稳定性等的表使用 MYISAM、STICK TO INNODB。事实上,你知道吗,根本不要使用 MYISAM。
    • 让我们坚持解决方案 1 和 2。我删除了上面的其他解决方案。感谢您的帮助。
    【解决方案3】:

    当您加入替换功能时,它必须使用替换评估每一行以查看它是否匹配。那就是让您选择每条记录,然后运行替换。此外,当您的第二个比较是使用当前行中的字段的子选择时。因此,对于 e 中的每一行,您都在针对 x 中的每一行进行测试,并且对于其中的每一行,您都在针对 p 的每一行进行测试。对于 xep 中的每一个,您还在运行另一个选择查询。您当然是在锻炼服务器。您可以做很多事情来加快速度。

    1. 使所有表的 naa 字段保持一致。删除“naa”。在 e 上,或将其添加到其他人,这样您就可以进行直接比较,而不是喜欢或替换功能。
    2. 预取您需要的最大日期,而不是运行子选择。罗德里戈对此的想法是正确的。
    3. 如果您不能执行其中任何一项,请将截断的值和匹配的日期选择到临时表中,然后运行您的选择并关闭它们的连接。

    执行 #1 可能会消除大部分减速,但这取决于有多少行与您的联接匹配。

    对于#2
    在 Rodrigo 的帖子中,他举了一个例子,但你不需要修剪功能。此外,为了获得最佳性能,您还应该索引日期字段。

    SET @MAX_XLBA = (select max(date) from xlba) 
    SET @MAX_3PLA = (select max(date) from 3pla) 
    SET @MAX_EVMBD = (select max(date) from evmbd) 
    SELECT e.cluster,e.vm,e.TotalCapacityGB,e.naa,p.array,x.array FROM evmbd AS e 
       LEFT JOIN xlba AS x ON x.naa = e.naa AND x.date = @MAX_XLBA 
       LEFT JOIN 3pla AS p ON p.naa = e.naa AND p.date = @MAX_3PLA 
       WHERE e.date = @MAX_EVMBD
    

    【讨论】:

    • 只是删除 naa。从一个表中将其从 300 秒降至 10 秒。感谢您的提示。我不确定如何完成最大日期的预取。你在哪里做这个?
    猜你喜欢
    • 1970-01-01
    • 2017-12-26
    • 1970-01-01
    • 2016-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-05
    • 2016-01-30
    相关资源
    最近更新 更多