MySQL,查询太慢,如何改进呢?

时间:2011-10-21 10:21:50

标签: mysql timeout

问题

我正在使用Workbench 5.2.35和MySQL服务器5.5运行查询,并且在查询稍有变化之后,我在600.516秒后出现错误“错误代码:2013。在查询期间丢失了与MySQL服务器的连接”。该查询有两个角色:

  1. 选择一种特殊类型的记录,其特征是在'col1'中具有'value1'(从A阶段传递到阶段B)
  2. 删除“col2”中的值与下一个结果的“col2”中的值相同的记录(从阶段B传递到阶段C)

    Stage A             Stage B             Stage C
    ***************     ***************     ***************
    *ID *col1*col2*     *ID *col1*col2*     *ID *col1*col2*
    ***************     ***************     ***************
    *1  * A  * a  *     *3  * C  * a  *     *3  * C  * a  *
    *2  * B  * a  *     *7  * C  * f  *     *7  * C  * f  *
    *3  * C  * a  *     *8  * C  * f  *     *16 * C  * b  *
    *4  * S  * a  *     *9  * C  * f  *     *18 * C  * c  *
    *5  * B  * a  *     *16 * C  * b  *
    *6  * A  * g  *     *17 * C  * b  *
    *7  * C  * f  *     *18 * C  * c  *
    *8  * C  * f  *
    *9  * C  * f  *
    *10 * A  * f  *
    *11 * B  * f  *
    *12 * D  * f  *
    *13 * S  * f  *
    *14 * F  * f  *
    *15 * F  * f  *
    *16 * C  * b  *
    *17 * C  * b  *
    *18 * C  * c  *
    
  3. 是一个概括: MySQL, select rows where a parameter value depends on the value that it has in a different row

    查询是:

    SELECT t.id, t.col2, t.col3, t.col4, t.col5 FROM tablename t
    WHERE t.id < 1000000
        AND t.col1 = 'value1' 
        AND t.col2 <> 
        (SELECT col2 FROM tablename
            WHERE col1 = 'value1' 
            AND id > t.id 
            LIMIT 1);
    

    错误原因

    现在,从这篇文章开始 https://serverfault.com/questions/29597/what-does-mysql-error-2013-mean 导致此错误的原因可能是:

    1. 有人杀了查询
    2. 网络问题导致连接死亡
    3. 服务器崩溃/死亡
    4. 您的连接因wait_timeout而空闲并被杀死
    5. 客户端没有足够快地为net_wait_timeout提取数据并被杀死
    6. 但由于查询在600.516秒停止,我猜这个案例中的问题是数字4(超时)。

      可能存在的问题和解决方案

      第一个想法是增加wait_timeout时间,但我认为这是由前一个错误触发的:查询不返回任何内容,而是继续运行。限制 t.id&lt; 1000000 用于在合理有限的子集中测试查询(数据库有大约2亿条目) 所以,我认为查询中存在一些问题,特别是在阶段B和阶段C之间的过程中(上一步很简单)

      非常感谢您对错误或查询的任何想法。

      由于


      解决方案

      这是工作代码,受到最佳答案的启发。命令DISTINCT工作,但最后我使用GROUP BY和ORDER BY以更好的方式呈现结果。

      SELECT id, col1, col2, ..., coln FROM tablename
          WHERE col1 = 'value1' 
          AND col2 = 'value2'
          ... 
          AND coln = 'valuen'
          GROUP BY col2
          ORDER BY id;
      

2 个答案:

答案 0 :(得分:0)

我会使用not in重写它,查询优化器有一个特殊情况 另外,我会使用不同的技巧将结果数限制为一。

limit的问题在于它首先创建一个临时表,其中全部结果,然后从中选择1行。

SELECT t.id, t.col2, t.col3, t.col4, t.col5 
FROM tablename t
WHERE t.id < 1000000
    AND t.col1 = 'value1' 
    AND t.col2 NOT IN 
    (SELECT col2 FROM tablename
        WHERE col1 = 'value1' 
        AND id = t.id+1)    <<--- assuming that `id` is the primary key.

如果你有一个复合索引(col1,col2)并使用id作为你的主键,那么查询不应该永远。

查看您的查询,我将其重写为:

SELECT t.id, t.col2, t.col3, t.col4, t.col5 
FROM tablename t
WHERE t.id IN ( 
  SELECT t2.id 
  FROM tablename t2
  WHERE t2.col1 = 'value1'
  GROUP BY t.col2)

如果我正确地研究了这些阶段,这应该可以解决问题。

答案 1 :(得分:0)

SELECT DISTINCT Par FROM table_name

http://www.w3schools.com/sql/sql_distinct.asp