如何优化limit

本文介绍了在不使用HAVING时,MySQL使用LIMIT row_count处理查询的不同方式。包括结合ORDER BY、DISTINCT、GROUP BY时的处理,以及发送行数、LIMIT 0的情况,还提到使用临时表查询时LIMIT子句对计算空间的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


在一些情况中,当你使用LIMIT row_count而不使用HAVING时,MySQL将以不同方式处理查询。

· 如果你用LIMIT只选择一些行,当MySQL选择做完整的表扫描时,它将在一些情况下使用索引。

· 如果你使用LIMIT row_count与ORDER BY,MySQL一旦找到了排序结果的第一个row_count行,将结束排序而不是排序整个表。如果使用索引,将很快。如果必须进行文件排序(filesort),必须选择所有匹配查询没有LIMIT子句的行,并且在确定已经找到第1个row_count行前,必须对它们的大部分进行排序。在任何一种情况下,一旦找到了行,则不需要再排序结果的其它部分,并且MySQL不再进行排序。

· 当结合LIMIT row_count和DISTINCT时,MySQL一旦找到row_count个唯一的行,它将停止。

· 在一些情况下,GROUP BY能通过顺序读取键(或在键上做排序)来解决,然后计算摘要直到关键字的值改变。在这种情况下,LIMIT row_count将不计算任何不必要的GROUP BY值。

· 只要MySQL已经发送了需要的行数到客户,它将放弃查询,除非你正使用SQL_CALC_FOUND_ROWS。

· LIMIT 0将总是快速返回一个空集合。这对检查查询的有效性是有用的。当使用MySQL API时,它也可以用来得到结果列的列类型。(该技巧在MySQL Monitor中不工作,只显示Empty set;应使用SHOW COLUMNS或DESCRIBE)。

· 当服务器使用临时表来进行查询时,使用LIMIT row_count子句来计算需要多少空间。

转载于:https://www.cnblogs.com/wjy0928/p/10884119.html

### 使用覆盖索引和子查询优化 SQL 查询中 `LIMIT` 子句的性能 #### 覆盖索引的作用 当查询只需要访问索引而不需要回表读取数据时,这种索引被称为覆盖索引。这能显著减少磁盘I/O次数并加快查询速度[^1]。 对于带有 `LIMIT` 的查询语句来说,如果能够构建合适的覆盖索引,则数据库引擎只需遍历少量的数据页就能获取到所需的结果集,从而极大地提高了效率。 #### 构建有效的覆盖索引 为了使 `LIMIT` 查询更高效,在设计索引时应考虑以下几个方面: - **选择合适列作为索引**:优先为那些频繁用于过滤条件(`WHERE`)、排序 (`ORDER BY`) 或者分组 (`GROUP BY`) 的字段创建索引。 - **确保所有涉及的列都在索引里**:为了让某个特定查询成为真正的“覆盖”,即完全依赖该索引来完成整个查询过程而不必再去查找实际表格中的记录,那么这个索引应该包含此查询所涉及到的所有非聚集键值以及任何其他必要的辅助属性列。 例如,假设有一个商品销售明细表 `sales_detail` ,其中包含如下几项重要信息: | id | product_id | sale_date | price | |--|------------|-----------|-------| | ...|... |... |... | 现在要找出最近三天内销量最高的前五名产品及其销售额度。此时就可以针对 `(sale_date DESC,product_id)` 创建复合索引,并将其设为覆盖索引以加速此类带有限制数量返回结果的操作。 ```sql CREATE INDEX idx_sales ON sales_detail(sale_date DESC, product_id); ``` 这样做的好处在于,当执行下面这条SQL命令的时候, ```sql SELECT product_id,SUM(price) AS total_price FROM sales_detail WHERE sale_date >= DATE_SUB(CURDATE(), INTERVAL 3 DAY) GROUP BY product_id ORDER BY SUM(price) DESC LIMIT 5; ``` MySQL可以直接从索引树结构中找到符合条件的产品ID列表,并计算它们各自的总价,而无需再回到原始表去检索具体的价格数值,进而提升了整体处理效能。 #### 利用子查询进一步提升性能 除了合理设置覆盖索例外,还可以借助子查询来改善含有 `LIMIT` 关键字的复杂查询的速度表现。特别是面对多层嵌套或者存在大量重复运算的情况下,适当重构逻辑关系往往可以获得意想不到的效果。 比如上述例子也可以改写成先求得各产品的总金额排名情况,然后再从中筛选出Top N条目;这样做不仅有助于减轻单次扫描的工作量,而且便于后续维护与扩展功能需求。 ```sql WITH ranked_products AS ( SELECT product_id, SUM(price) OVER (PARTITION BY product_id ORDER BY sale_date DESC ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) as cumulative_total, RANK() OVER(ORDER BY SUM(price) DESC) rank_num FROM sales_detail WHERE sale_date >= DATE_SUB(CURDATE(), INTERVAL 3 DAY) ) SELECT product_id,cumulative_total FROM ranked_products WHERE rank_num<=5 ; ``` 这种方法通过窗口函数实现了累积求和的同时完成了初步排序工作,最后仅需简单选取指定范围内的成员即可达成目标。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值