【问题标题】:Select with Inner Join operator and IN (long results) - Optimize Query使用 Inner Join 运算符和 IN(长结果)选择 - 优化查询
【发布时间】:2023-03-31 07:35:01
【问题描述】:

我执行MySql 查询,在两个不同的表中查找结果。

表格
合同
id, contract, creditor_id, client_id, event_id

发票
id、contract_id、发票、到期、价值

想法是在查询中使用一些参数来选择合约,例如:
initial delayfinalinitial valuefinal事件债权人

为此,我使用INNER JOINHAVINGIN

详情:
收到结果后,我取值并循环对每个查询结果进行更新,使用结果ID。

为了更好的可视化,我在SQL Fiddle 中构建了一个示例。

问题是,当我用很长的结果或数千行查询时,查询真的很慢。

所以,我想知道是否有更好的方法以最佳方式执行相同的查询。

查询:

SELECT `c`.`id`,
       `c`.`contract`,
       `c`.`creditor_id`,
       `c`.`client_id`,
       `c`.`event_id`,
       `t`.`total_value`,
       `delay`
FROM `contract` `c`
INNER JOIN
  (SELECT contract_id,
          Sum(value) total_value,
          Datediff(Curdate(), due) AS delay
   FROM invoice t GROUP  BY contract_id
   HAVING delay <= 99999
   AND delay >= 1
   AND total_value >= 1
   AND total_value < 99999) t ON `t`.`contract_id` = `c`.`id`
WHERE `c`.`creditor_id` = 1
  AND `c`.`event_id` IN(4, 7, 5, 8, 13, 3, 6, 15, 2, 24, 1, 21, 20, 14, 17, 18, 16, 23, 25, 22, 9, 10, 26, 12, 19, 11)

【问题讨论】:

  • 小提琴链接坏了?
  • 还为您的慢查询提供执行计划,如果有的话,还提供两个表上的索引信息
  • 乍一看,我可以说你的内部 SELECT 语句肯定会导致延迟
  • 当你做 GROUP BY contract_id 时,你正在服用哪个 due
  • 子查询与sql_mode=only_full_group_by不兼容

标签: mysql sql query-optimization


【解决方案1】:
  • 如果“1..99999”表示“任何值”,则从查询中删除测试。那就是当用户想要一个开放式测试时构造一个不同的查询。

  • 处理GROUP BY中缺少due

  • Datediff(Curdate(), due) &gt; 123 更改为due &lt; CURDATE() - INTERVAL 123 DAY。这将使我们有机会在INDEX 中使用due

  • 限定duevalue;我们不知道他们在哪张桌子上。

  • 请提供SHOW CREATE TABLE

  • c 可以使用INDEX(creditor_id, event_id),但是在解决了以上问题之后,可能会有更好的索引。

【讨论】:

  • 我需要使用1 ... 99999,因为这样我查找所有迟到的合约,就像1 to 365一样,查找所有延迟为1的合约年。我可以延迟 1.2...20 年的合同,我需要能够过滤这些。
猜你喜欢
  • 2018-01-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-11
  • 1970-01-01
  • 2016-06-09
  • 2012-02-02
  • 1970-01-01
相关资源
最近更新 更多