【问题标题】:Query Optimization of group concat querygroup concat查询的查询优化
【发布时间】:2019-11-04 01:20:49
【问题描述】:

我有以下数据库架构 -

shop_orders(id, project_id, selling_price, tax_amount, ...)

project_contacts(id, project_id, contact_id, ...)

projects(project_id, project_contact_id, site_contact_id, ...)

样本数据 -

shop_orders(1, 123456, 24.35, 2.34, ...)
project_contacts(1, 123456, 10001, ...)
projects(123456, 10001, 10002, ...)

期望的输出 -

123456:26.69

我正在尝试执行以下查询 -

SELECT GROUP_CONCAT(CONCAT(project_id, ':', (`selling_price` + `tax_amount`))) AS project_amount 
FROM shop_orders 
WHERE project_id IN (
   SELECT project_id FROM project_contacts WHERE contact_id=10001 
   UNION SELECT project_id FROM projects WHERE project_contact_id=10001 
   UNION SELECT project_id FROM projects WHERE site_contact_id=10001 
)

此查询在项目表大小约为 800 的演示服务器中运行良好,而在生产服务器中不起作用 [即它只是继续在僵尸状态下运行,] 项目表大小约为 9000。

请让我知道优化查询的任何指示。

编辑

即使这个查询也没有返回任何响应 -

SELECT CONCAT(project_id, ':', (`selling_price` + `tax_amount`)) AS project_amount 
FROM shop_orders 
WHERE project_id IN (
  SELECT project_id FROM project_contacts WHERE contact_id=10001 
  UNION SELECT project_id FROM projects WHERE project_contact_id=10001 
  UNION SELECT project_id FROM projects WHERE site_contact_id=10001
)

虽然如果我运行类似的查询 -

SELECT CONCAT(project_id, ':', (`selling_price` + `tax_amount`)) AS project_amount 
FROM shop_orders WHERE project_id IN (NULL)

它会立即返回答案。另一个联合查询也单独运行得很好。我可以分别运行这两个查询,但不确定为什么单个查询不返回输出。

【问题讨论】:

  • "while it doesn't work" ???我猜截断错误:stackoverflow.com/a/4469523/5070879
  • @LukaszSzozda 我对此表示怀疑,因为没有组 concat 的原始查询不会返回任何响应..请检查编辑
  • 样本数据、预期结果和逻辑解释都会有所帮助。
  • @GordonLinoff 添加了所需的输出和示例数据。谢谢
  • 什么版本? (这方面的优化器有很大的变化。)请提供EXPLAIN SELECT ...

标签: mysql sql performance optimization


【解决方案1】:

我将首先使用EXISTS 来表达查询:

SELECT GROUP_CONCAT(CONCAT(project_id, ':', (`selling_price` + `tax_amount`))) AS project_amount 
FROM shop_orders so
WHERE EXISTS (SELECT 1
              FROM project_contacts pc
              WHERE pc.project_id = so.project_id AND
                    pc.contact_id = 10001
             ) OR
      EXISTS (SELECT 1
              FROM project p
              WHERE p.project_id = so.project_id AND
                    p.project_contact_id = 10001
             ) OR
      EXISTS (SELECT 1
              FROM project p
              WHERE p.project_id = so.project_id AND
                    p.site_contact_id = 10001
             );

为了获得最佳性能,您需要以下索引:

  • project_contacts(project_id, contact_id)
  • project(project_id, projecct_contact_id)
  • project(project_id, site_contact_id)

我应该注意到CONCAT()GROUP_CONCAT() 中是多余的,因为它需要多个参数:

SELECT GROUP_CONCAT(project_id, ':', (`selling_price` + `tax_amount`)) AS project_amount 

【讨论】:

  • 它工作得很好,存在创造了如此多的差异,我会确保继续使用它。非常感谢
  • 即使数据达到 10k 行时查询停止,我可以通过以编程方式触发多个查询来完成这些事情,但效率最低。
猜你喜欢
  • 2018-03-12
  • 2011-08-29
  • 1970-01-01
  • 1970-01-01
  • 2021-01-23
  • 2022-09-22
  • 1970-01-01
  • 2012-12-31
  • 1970-01-01
相关资源
最近更新 更多