【问题标题】:MySQL basic query taking exceptionally long - explain plan looks pretty goodMySQL 基本查询耗时特别长 - 解释计划看起来不错
【发布时间】:2017-03-01 10:15:48
【问题描述】:

我对下面的解释计划有疑问。这是非常基本的,每个连接都使用一个索引(虽然不是唯一的),并且需要 5 个多小时。最大的表有大约 100k 条记录。 RAM 和 CPU 没有挂钩或任何东西,没有其他查询运行,没有表锁。我拥有的最“复杂”的部分是外连接中的合并。这是要我死吗?

为了澄清,我加入同一个表两次,因为有些记录有一个用户 ID,有些只有名字/姓氏。显然我更喜欢通过唯一的用户名加入,其中一项选择是 coalesce(u1.job_title, u2.job_title)

from utilization_incident ui

left join users_utilization_v u1
       on  u1.cc_user_id = ui.assigned_to_user_id
       and u1.source_system = ui.source
       and u1.data_date = ui.data_date
left join users_utilization_v u2
       on  u2.first_name = ui.assigned_to_first_name
       and u2.last_name = ui.assigned_to_last_name
       and u2.source_system = ui.source
       and u2.data_date = ui.data_date

left join lkp_job_title_service_area jtsa
       on  jtsa.job_title = coalesce(u1.job_title, u2.job_title)

【问题讨论】:

  • 简单:尝试在没有coalesce 的情况下运行 SQL,看看它是否明显更快
  • 如果不深入了解数据之间的关系(以及可用的确切索引),很难给出太多建议;但是...是的,作为连接条件的合并可能对您没有任何帮助;它可能导致对所涉及的两个表进行全表扫描。您最好使用两个单独的连接到该表(一个连接到 u1,另一个连接到 u2)并决定在选择列表中使用哪个连接 jtsa 的值。
  • 另外,当您可以组合加入条件时,您需要加入users_utilization_v 两次,这并不是很清楚。 ORs 在连接条件中很少是最优的,但也不是不必要的连接。
  • LEFT 收集缺失的行——你真的想要吗?

标签: mysql performance join coalesce explain


【解决方案1】:

CPU 可能没有挂钩,但 I/O 呢?

多少内存? innodb_buffer_pool_size的值是多少?

请提供SHOW CREATE TABLE.
请提供完整的SELECT
请提供EXPLAIN SELECT ...的文字版。

等待更多细节,这些索引应该会有所帮助:

users_utilization_v: INDEX(cc_user_id, source_system, data_date)
users_utilization_v: INDEX(first_name, last_name, source_system, data_date)
lkp_job_title_service_area: INDEX(job_title)

删除LEFT,除非你需要它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-12
    • 1970-01-01
    • 2010-09-09
    • 1970-01-01
    相关资源
    最近更新 更多