Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 子查询执行时间:localhost=2秒/server=98+;秒_Mysql_Subquery - Fatal编程技术网

Mysql 子查询执行时间:localhost=2秒/server=98+;秒

Mysql 子查询执行时间:localhost=2秒/server=98+;秒,mysql,subquery,Mysql,Subquery,我可以在子查询方面寻求帮助吗 当我在本地XAMP mySQL数据库上运行查询时,查询需要2秒钟才能完成。然而,在我的Web服务器上使用相同的数据库时,相同的查询需要98秒以上的时间才能返回相同的结果 当我说相同时,记录是从HeidiSQL导出和插入的,因此我确信数据集是正确的。数据库DDL也是从HeidiSQL创建的,但我猜我可能错过了创建数据库精确副本的一些关键步骤 我还使用Heidi的导出功能创建了一个。尽管我应该指出,在小提琴上执行查询比在现实生活中要快得多 我正在执行的查询是 SELEC

我可以在子查询方面寻求帮助吗

当我在本地XAMP mySQL数据库上运行查询时,查询需要2秒钟才能完成。然而,在我的Web服务器上使用相同的数据库时,相同的查询需要98秒以上的时间才能返回相同的结果

当我说相同时,记录是从HeidiSQL导出和插入的,因此我确信数据集是正确的。数据库DDL也是从HeidiSQL创建的,但我猜我可能错过了创建数据库精确副本的一些关键步骤

我还使用Heidi的导出功能创建了一个。尽管我应该指出,在小提琴上执行查询比在现实生活中要快得多

我正在执行的查询是

SELECT  d.dayID, d.dayDate, d.item, w.Idx, w.word, w.wordID, w.asize, w.span
FROM words w
    INNER JOIN days d ON w.dayID = d.dayID
    WHERE w.word IN (
            SELECT w1.word
            FROM words w1
                INNER JOIN days d1 ON w1.dayID = d1.dayID
            WHERE d1.dayDate = '2012-02-27'
                AND d1.Item = 'a'
                AND w1.span  = 24
                AND w1.asize = 6
            )
    AND w.span = 24
    AND w.asize = 6
GROUP BY d.dayDate, d.item 
Order by d.dayDate, w.asize DESC, w.Idx;
它的目的是从Days表返回日期和项目的列表,其中word表中有重复的单词

上面的查询将返回与此类似的结果

dayID   dayDate         item    Idx     word        wordID      asize   span
1974    2012-11-22      B       3       item b      1367339     6       24
4370    2015-03-10      B       1       item b      3024989     6       24
使用phpMyAdmin,我在word字段中添加了一个索引,这使时间从98秒减少到46秒。但是,46秒当然也太长了

另外需要注意的是,单词表实际上包含大约300万条记录。其他查询(非子查询)在眨眼之间运行。我想我只是不擅长子查询


我想问一下,有没有人能为我指出正确的方向,以确定为什么在服务器上执行查询会花费如此长的时间?

一般来说,在处理复杂或大的子查询时,应该避免在中使用
。这是因为
中的
条件必须为数据源中的每一行计算一次。因此,如果您的数据源有1000行,并且
条件中的
有1000个元素,则执行如下:

  • 对于第1行,运行子查询并检查该值是否在子查询结果中
  • 对于第2行,运行子查询并检查该值是否在子查询结果中
  • 等等
(不用说,如果子查询很复杂,这将是一个巨大的性能损失)

所以,你可以做一些事情来加快速度:

  • 不要在
  • 中使用
    ,而是使用
    加入
  • 不要使用子查询,而是创建一个临时表,添加适当的索引,然后使用
    JOIN
  • 我将处理选项2。如果需要,可以用完整的子查询替换临时表

    那么,让我们创建一个临时表:

    drop table if exists temp_words;
    create temporary table temp_words
        SELECT w1.word
        FROM words w1
            INNER JOIN days d1 ON w1.dayID = d1.dayID
        WHERE d1.dayDate = '2012-02-27'
          AND d1.Item = 'a'
          AND w1.span  = 24
          AND w1.asize = 6;
    alter table temp_words
        add index w(word);
    
    现在,不要在
    中使用
    ,而是使用
    加入

    SELECT  d.dayID, d.dayDate, d.item, w.Idx, w.word, w.wordID, w.asize, w.span
    FROM words w
        INNER JOIN days d 
                ON w.dayID = d.dayID
        INNER JOIN temp_words as w1 -- Replace 'temp_words' with your subquery 
                                    -- if you don't want to use a temp table
                ON w.word = w1.word
    WHERE w.span = 24
      AND w.asize = 6
    GROUP BY d.dayDate, d.item 
    Order by d.dayDate, w.asize DESC, w.Idx;
    
    我想您会注意到,通过使用
    JOIN
    而不是
    中的
    ,可以大大提高性能

    关于临时表,您必须了解的事项:

  • 它们的行为类似于普通表,因此您可以像使用任何其他表一样使用它们:您可以插入、更新和删除行,您可以添加索引或以任何方式更改它们,如果它们不再有用,您可以删除它们
  • 它们仅对创建它们的连接可见。这意味着两个连接可以创建具有相同名称(但可能具有不同结构)的临时表,并且每个连接可以使用自己的“副本”
  • 一旦连接关闭或终止,它们将被删除,因此如果关闭或终止连接,则必须再次创建它们

  • 哇,多好的回答啊。有很多东西需要学习和吸收。关于删除子查询。。。我很乐意。我只是觉得它们非常混乱和复杂。非常感谢。我会尝试你的建议和更新留下评论+我现在很高兴,这只是SQL巫术。我为我的测试选择了更简单的选项。。。这就是“用子查询替换临时单词”,因为这是一个快速测试。从98秒(我的最佳时间)到0.125秒(WTF)与您的加入。我需要用你提到的其他信息进行更多的测试。我特别想看看这些“临时表”。。。我觉得他们会很有帮助。我以前听说过它们,但从来没有觉得我有理由使用它们,所以我就忽略了它们。不管怎样,我接受了你的回答,并把你推到了我的“给这些人买杯啤酒”名单的首位。我认为,当有人提供帮助时,查看他们的个人资料是一种礼貌。通常也有“额外”的宝石需要学习。我遵循了您提供的链接,在同意内容的同时,我必须承认我也犯了没有首先应用“您尝试了什么”原则的错误。有时候,真的不知道从哪里开始,但有时候是懒惰。它只是强调了努力的重要性——即使它走错了方向。@Johnny很乐意帮忙!临时表是将大任务分解为小步骤的强大工具:它们可以用于许多“分而治之”的解决方案。至于你的其他评论,我只能说:既然你知道这种方法,那么就使用它并向前支付;这样每个人都赢了!(是的,喝杯啤酒就好了!)再次谢谢你,巴兰卡。我从你身上学到了很多东西。我也会尽力提前付款。干杯。今天我将尝试一些测试,并根据Barranka的建议更新Q。