Mysql SQL查询性能差异

Mysql SQL查询性能差异,mysql,sql,Mysql,Sql,我有一个有一百万条记录的表,我设计了两个查询 表索引: id = primary bedroom = index elevator = index pricemeter = index dateadd = index 我想知道为什么这个查询: SELECT * FROM ( SELECT * FROM `p_apartmentbuy` WHERE `sqm` > 100 AND `bedroom` &

我有一个有一百万条记录的表,我设计了两个查询

表索引:

id = primary
bedroom = index
elevator = index
pricemeter = index
dateadd = index
我想知道为什么这个查询:

SELECT 
    *
FROM (
    SELECT 
        * 
    FROM `p_apartmentbuy` 
    WHERE
        `sqm` > 100
        AND `bedroom` > 1
        AND `elevator` = 1
        AND `pricemeter` < 5999999
    ORDER BY `id` DESC
    LIMIT 0, 30
) AS `alias`
ORDER BY `id` DESC, `dateadd` DESC
比这个快得多:

SELECT 
    * 
FROM `p_apartmentbuy` 
WHERE
    `sqm` > 100
    AND `bedroom` > 1
    AND `elevator` = 1
    AND `pricemeter` < 5999999
ORDER BY `id` DESC, `dateadd` DESC
LIMIT 0, 30
第一次查询耗时0.0027秒,第二次查询耗时5.6848秒。 这两个结果与其他结果相同,where子句上的变量是示例

解释快速查询:

解释慢速查询:
您的表必须使用ID作为主键。在这种情况下,将使用ID列对行进行索引,并且所有数据都已按ID排序

因此,对于mysql计划来说,获取前30行是很快的。那就订那30排吧我会很快的

第二个查询必须返回所有行,以便根据“dateadd”列进行排序。然后将计算限制条款


我希望这能回答您的问题。

第二个查询必须按id和dateadd对整个数据集进行排序,然后才能应用限制


另一方面,第一个查询提前返回,只有30条记录,然后按id和dateadd排序。更少的工作。

好吧,我们需要更多关于索引的信息,但简单看一下这些查询就会发现它们是不同的。它们也可能产生不同的结果,只是巧合,根据数据的结构,它们很可能是相同的。在第一个查询中,您选择了30行,按id排序,它可能有一个索引,然后按dateadd排序,这非常简单。您的第二个查询必须按这两列对所有一百万条记录进行排序,然后选择30条,这样显然会更昂贵。

Explain将确认这一点

但第一个是通过id获取前30条记录,这可能是主键,因此按id排序不需要排序。然后就把那30个分类

第二种方法是不按顺序获取所有记录,然后按id和日期对它们进行排序,然后取前30个

可能是dateadd上的索引


不过只能猜测。

执行计划说明了什么?请在选择之前使用“解释”,这样我们可以在运行查询之前查看执行计划,并确保SQL缓存为空。之所以更快,就像一些人回答的那样。发生的情况是,较慢的查询也会按dateadd对数据集排序,而较快的派生表则不会。这里还有一件有趣的事情,叫做延迟行查找。详细解释。id和dateadd都没有索引,跑掉了。在id上加一个索引,快速的那个将是冒泡的。@hamidreza66:这只是重申了这是两列的排序。这两个查询的最大区别在于,您可能无法在第一个查询的结果中获取最新的dateadd。由于返回的30是按id排序的,因此它也不是按dateadd排序的,因此如果您的id在第29行或第30行重复,它可能返回了最新的dateadd。最终结果是按dateadd排序的。我将这两个查询作为一个整体来讨论:您可能想更改我的编辑,但我发现这很混乱,因为上面的第二个查询是按id和dateadd排序的,第一个查询是按id排序的,然后是有限的,然后是其余30个按id和dateadd排序的查询。@vol7ron:是的,有点混乱。感谢您的反馈:ID是主键,where子句中的所有字段都已被索引第一次查询还应按ID对所有百万条记录进行排序,索引只应在筛选中发挥作用,而不是在排序中发挥作用。唯一可能搞砸这件事的是内部dateadd排序,因为正如您所建议的,它在多行中对两列进行排序,而不是一列。