【问题标题】:Does using LIMIT in mysql queries will make my application faster and efficient?在 mysql 查询中使用 LIMIT 会使我的应用程序更快更高效吗?
【发布时间】:2014-01-21 09:01:11
【问题描述】:

假设我在一个表中有超过 100 万条记录。以下哪个代码将更快、更高效地返回结果?我用过php。

我应该使用这个吗?

$query = mysql_query("select count(*) as count from reversals where seen = 'false'");
while($q = mysql_fetch_array($query))
    {
    $limit = $q['count'];
    }

$query2 = mysql_query("select * from reversals where seen = 'false' limit $limit");
while($q = mysql_fetch_array($query))
    {
    echo $q['amount'];
    }

或者:

$query = mysql_query("select * from reversal where seen = 'false'");
while($q = mysql_fetch_array($query2))
    {
    echo $q['amount'];
    }

【问题讨论】:

  • 如果您的结果决定可以用 2 行来做出,那么当然这将有助于只获得 2 行而不是 20,0000。但是有些情况是你不能限制的
  • 它与性能无关,而与应用程序逻辑有关。您需要执行多少行?
  • 您可能会发现这很有用。 stackoverflow.com/questions/17540857/…>
  • 您可能会发现这很有用stackoverflow.com/questions/17540857/…>

标签: php mysql


【解决方案1】:

好的,可以在这里回答您的问题,我有一个名为 paymentlog 的表,其中有 709231 条记录。出于测试目的,我确保它没有任何索引,特别是在 where 条件中使用的列。

我使用了 EXPLAIN,我得到了一些东西

explain select * from paymentlog where transdate = '2012-12-01' limit 10 ; 

+----+-------------+------------+------+---------------+------+---------+------+--------+-------------+
| id | select_type | table      | type | possible_keys | key  | key_len | ref  | rows   | Extra       |
+----+-------------+------------+------+---------------+------+---------+------+--------+-------------+
|  1 | SIMPLE      | paymentlog | ALL  | NULL          | NULL | NULL    | NULL | 709231 | Using where |
+----+-------------+------------+------+---------------+------+---------+------+--------+-------------+

即使我添加了 LIMIT,您也可以看到它正在扫描表中的所有行。所以 LIMIT 不会让你的查询更快,它只会减少数据量。

现在,如果我在上表中为 transdate 添加索引并运行相同的说明,我会得到 ​​p>

+----+-------------+------------+------+--------------------+--------------------+---------+-------+------+-------+
| id | select_type | table      | type | possible_keys      | key                | key_len | ref   | rows | Extra |
+----+-------------+------------+------+--------------------+--------------------+---------+-------+------+-------+
|  1 | SIMPLE      | paymentlog | ref  | plog_transdate_idx | plog_transdate_idx | 3       | const | 1069 |       |
+----+-------------+------------+------+--------------------+--------------------+---------+-------+------+-------+

所以现在报告的扫描行数是 1069,即使它不太可能扫描 1069 行,它会在找到限制值时停止,但是如果我们得到的值是 1000,70,那么它需要扫描到1069,所以减少了表中的扫描行,因为索引在where条件下,优于709231。

所以结论是通过使用索引可以减少被扫描的行数,但是如果你限制相同的行数将被扫描,最多索引 1069 而没有索引 709231。

【讨论】:

  • 实际上EXPLAIN 中的rows 只是一个预测,它与实际扫描的行数无关。因此,不应基于该数字做出那么多假设
  • "但它总是会扫描 where 条件为 1069 的匹配行" --- 那是 错误。对于给定的查询,它只需要 10 个顶部行而不“扫描”其他 1059
【解决方案2】:

您的第一个代码示例计算行数,然后选择所有行(假设没有修改此表的并发会话)。

这实际上意味着您无论如何都要选择整个表格,因此LIMIT 在那里没有意义(并且也不影响性能)。

无论您在哪里阅读过它 - 都认为添加 LIMIT 会自动使您的查询更快,这是一个错误的假设。

Mysql 性能优化一个复杂的话题,而且通常没有多少通用的建议适用于所有人和每种情况。

因此,如果您对 mysql 性能有任何真正问题 - 请解释您遇到的确切问题,提供真正的数据库架构、一些有关数据的统计信息等

【讨论】:

    【解决方案3】:

    在大多数情况下,如您的示例,YES,因为当达到限制时 mysql 将停止扫描结果。

    但是如果结果的生成是基于某种东西,比如 ORDER BY, LIMIT 会有所帮助,但它可能没有预期的速度。

    SELECT * FROM table WHERE indexed_field = 2 LIMIT 10; //fast
    SELECT * FROM table WHERE indexed_field = 2 ORDER BY noindexfield LIMIT 10; //less faster, uses filesort.
    

    使用mysql的explain优化SELECTS。 使用 GROUP BY 时会变得更加复杂。

    【讨论】:

      【解决方案4】:

      是的,

      从 db 中获取一堆行比获取整个内容更快更好......

      PHP 中我们可以实现 Pagination....

      【讨论】:

        猜你喜欢
        • 2011-09-11
        • 1970-01-01
        • 2012-01-18
        • 2015-03-16
        • 2018-05-17
        • 1970-01-01
        • 2013-02-10
        • 1970-01-01
        • 2011-09-21
        相关资源
        最近更新 更多