【问题标题】:mysql query takes 400 sec to executemysql查询需要400秒才能执行
【发布时间】:2014-02-28 18:40:06
【问题描述】:

这是需要 400 秒才能加载的查询。我直接在mysql中试过。如果我单独尝试子查询,所有子查询都会在不到 0.01 秒内执行。 在 40 秒内查询联合后的所有执行。联合之前的查询全部在 1 秒内执行。

sales 表和 salesaff 表均包含大约 12K 条记录。此查询的目的是当 vendor=affiliate 在 sales 表中时,我需要从 salesaff 表中添加 id 与 sales 表中的搜索条件匹配的行。

 (
 SELECT 'no' AS aff, ss.orderid,ss.saletype,ss.price,ss.salests 
    FROM sales ss 
    WHERE 1=1 AND 
        ( ss.vendor='3kpertrade' OR ss.affiliate='3kpertrade') 
  ) 

 UNION ALL 

 ( 
 SELECT 'yes' AS aff, sf.orderid,sf.saletype,sf.price,sf.salests 
 FROM salesaff sf 
 WHERE sf.vendor=sf.affiliate AND 
 sf.orderid IN (SELECT ss.orderid from sales ss WHERE 1=1 
               AND ( ss.vendor='3kpertrade' OR ss.affiliate='3kpertrade') 
               GROUP BY ss.orderid ) 
 ) 

 ORDER BY salests DESC

【问题讨论】:

  • Where 1=1 业务有什么用?没必要。另外,请格式化您的 SQL,以便我们阅读。
  • 尝试不使用 order by 子句,看看效果如何。
  • 1=1 是编写动态查询,以便我可以从脚本中添加 AND column=condition。我删除了 1=1 并尝试不改变性能。
  • 第二个查询本身需要 40 秒,改进了无顺序 4 秒。
  • 尝试使用 EXPLAIN 查看瓶颈在哪里。 slideshare.net/phpcodemonkey/mysql-explain-explained

标签: mysql sql union-all


【解决方案1】:

尝试启动这个:

EXPLAIN ( SELECT 'no' AS aff, ss.orderid,ss.saletype,ss.price,ss.salests FROM sales ss WHERE 1=1 AND ( ss.vendor='3kpertrade' OR ss.affiliate='3kpertrade') )

UNION ALL

( SELECT 'yes' AS aff, sf.orderid,sf.saletype,sf.price,sf.salests FROM salesaff sf WHERE sf.vendor=sf.affiliate AND

sf.orderid IN ( SELECT ss.orderid from sales ss WHERE 1=1 AND ( ss.vendor='3kpertrade' OR ss.affiliate='3kpertrade') GROUP BY ss.orderid ) )

ORDER BY salests DESC

检查“key”列是否永远不会为空,否则将索引添加到提到的列。

如果没有帮助,请查看以下答案:https://dba.stackexchange.com/questions/7806/copying-to-tmp-table-extremely-slow

【讨论】:

  • 嗯,你好像没有索引。试试这个:ALTER TABLE sales ADD KEY key_vendor(vendor), ADD KEY key_salests(salests), ADD KEY key_affilate(affiliate);ALTER TABLE salesaff ADD KEY key_vendor(vendor), ADD KEY key_salests(salests), ADD KEY key_affilate(affiliate); 然后重新启动查询。
  • 谢谢。在两个行中没有键出现在两个行中,选择类型为Union时,键是null。 span>
  • 添加了这些索引但没有改进。
【解决方案2】:

我认为它试图在查询执行期间进行排序。这可能会有所帮助:

SELECT * FROM (
(
 SELECT 'no' AS aff, ss.orderid,ss.saletype,ss.price,ss.salests 
    FROM sales ss 
    WHERE 1=1 AND 
        ( ss.vendor='3kpertrade' OR ss.affiliate='3kpertrade') 
  ) 

 UNION ALL 

 ( 
 SELECT 'yes' AS aff, sf.orderid,sf.saletype,sf.price,sf.salests 
 FROM salesaff sf 
 WHERE sf.vendor=sf.affiliate AND 
 sf.orderid IN (SELECT ss.orderid from sales ss WHERE 1=1 
               AND ( ss.vendor='3kpertrade' OR ss.affiliate='3kpertrade') 
               GROUP BY ss.orderid ) 
 ) 
)
ORDER BY salests DESC

【讨论】:

  • 错误:每个派生表都必须有自己的别名
  • 尝试为联合中的两个查询添加别名:select * from ((query 1) a union all (query 2) b) order by...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-02-13
  • 1970-01-01
  • 1970-01-01
  • 2017-02-24
  • 1970-01-01
  • 1970-01-01
  • 2017-12-26
相关资源
最近更新 更多