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



问题

我正在使用工作台5.2.35和MySQL服务器5.5运行查询,我有错误"错误代码:2013。在600.516秒后,在查询过程中失去与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  *
    

,是以下情况的概括:MySQL,选择一个参数值依赖于它在另一行中的值的行

查询为:

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. 您的连接空闲等待超时,并被杀死
  5. 客户端没有在net_wait_timeout时间内快速提取数据并被杀死

,但由于查询在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;

SELECT DISTINCT Par FROM table_name

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

我会用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)

如果我正确地研究了这些阶段,这应该能奏效。

相关内容

  • 没有找到相关文章

最新更新