Mysql Limit操作

select * from table LIMIT 5,10; #返回第6-15行数据
select * from table LIMIT 5; #返回前5行
select * from table LIMIT 0,5; #返回前5行


性能优化:

基于MySQL5.0中limit的高性能,我对数据分页也重新有了新的认识.

1.
Select * From cyclopedia Where ID>=(
Select Max(ID) From (
 Select ID From cyclopedia Order By ID limit 90001
) As tmp
) limit 100;

2.
Select * From cyclopedia Where ID>=(
Select Max(ID) From (
 Select ID From cyclopedia Order By ID limit 90000,1
) As tmp
) limit 100;

同样是取90000条后100条记录,第1句快还是第2句快?
第1句是先取了前90001条记录,取其中最大一个ID值作为起始标识,然后利用它可以快速定位下100条记录
第2句择是仅仅取90000条记录后1条,然后取ID值作起始标识定位下100条记录
第1句执行结果.100 rows in set (0.23) sec
第2句执行结果.100 rows in set (0.19) sec

很明显第2句胜出.看来limit好像并不完全像我之前想象的那样做全表扫描返回limit offset+length条记录,这样看来limit比起MS-SQL的Top性能还是要提高不少的.

其实第2句完全可以简化成

Select * From cyclopedia Where ID>=(
Select ID From cyclopedia limit 90000,1
)limit 100;

直接利用第90000条记录的ID,不用经过Max运算,这样做理论上效率因该高一些,但在实际使用中几乎看不到效果,因为本身定位ID返回的就是1条记录,Max几乎不用运作就能得到结果,但这样写更清淅明朗,省去了画蛇那一足.

可是,既然MySQL有limit可以直接控制取出记录的位置,为什么不干脆用Select * From cyclopedia limit 90000,1呢?岂不更简洁?
这样想就错了,试了就知道,结果是:1 row in set (8.88) sec,怎么样,够吓人的吧,让我想起了昨天在4.1中比这还有过之的"高分".Select * 最好不要随便用,要本着用什么,选什么的原则, Select的字段越多,字段数据量越大,速度就越慢. 上面2种分页方式哪种都比单写这1句强多了,虽然看起来好像查询的次数更多一些,但实际上是以较小的代价换取了高效的性能,是非常值得的.

第1种方案同样可用于MS-SQL,而且可能是最好的.因为靠主键ID来定位起始段总是最快的.

Select Top 100 * From cyclopedia Where ID>=(
Select Top 90001 Max(ID) From (
 Select ID From cyclopedia Order By ID
) As tmp
)

但不管是实现方式是存贮过程还是直接代码中,瓶颈始终在于MS-SQL的TOP总是要返回前N个记录,这种情况在数据量不大时感受不深,但如果成百上千万,效率肯定会低下的.相比之下MySQL的limit就有优势的多,执行:
Select ID From cyclopedia limit 90000
Select ID From cyclopedia limit 90000,1
的结果分别是:
90000 rows in set (0.36) sec
1 row in set (0.06) sec
而MS-SQL只能用Select Top 90000 ID From cyclopedia 执行时间是390ms,执行同样的操作时间也不及MySQL的360ms.  

MySQL 的 `LIMIT` 子句用于限制 SQL 查询返回的行数。这在处理大型数据集时非常有用,尤其是在分页、性能优化或获取前 N 条记录等场景中。 ### 语法 基本语法如下: ```sql SELECT column_list FROM table_name ORDER BY sort_column LIMIT [offset,] row_count; ``` - **row_count**:指定要返回的最大行数。 - **offset**(可选):指定从第几行开始返回结果(偏移量),默认为 0。 ### 使用示例 #### 1. 获取前 N 条记录 若只想获取查询结果中的前 5 条记录: ```sql SELECT * FROM employees ORDER BY salary DESC LIMIT 5; ``` 此查询将按薪资降序排列员工,并仅返回薪资最高的前 5 名员工。 #### 2. 分页查询 在 Web 应用程序中实现分页功能时,`LIMIT` 常与 `OFFSET` 一起使用。例如,每页显示 10 条记录,查看第 2 页的数据: ```sql SELECT * FROM orders ORDER BY order_date DESC LIMIT 10 OFFSET 10; ``` 该语句跳过前 10 条记录,返回接下来的 10 条记录。 #### 3. 避免不必要的排序开销 如果不需要特定排序,可以省略 `ORDER BY`,但通常建议使用以确保一致性: ```sql SELECT product_id, product_name FROM products LIMIT 20; ``` 此查询将返回产品表中的任意 20 条记录。 #### 4. 与子查询结合使用 有时需要结合子查询来获取更精确的结果。例如,获取薪资排名第 6 到第 10 的员工: ```sql SELECT * FROM ( SELECT * FROM employees ORDER BY salary DESC LIMIT 10 ) AS top_10 ORDER BY salary ASC LIMIT 5 OFFSET 5; ``` 内部查询先获取前 10 名高薪员工,外部查询再从中选出后 5 名。 ### 注意事项 - **性能影响**:`LIMIT` 通常有助于提高查询性能,尤其是当数据库知道它只需要返回一定数量的行时。但如果配合较大的 `OFFSET` 使用(如分页到很远的位置),可能会导致性能下降,因为数据库仍需扫描并丢弃前面的大量行。 - **索引利用**:为了提升效率,确保排序字段上有合适的索引,特别是在大数据量表上执行分页操作时。 ### 优化建议 - 对于深度分页(如 `LIMIT 10000, 10`),考虑使用基于游标的分页方法,即通过唯一递增 ID 或时间戳进行分段查询,避免大偏移量带来的性能问题。 - 在某些情况下,可以结合分区表或物化视图来进一步优化大规模数据下的分页性能。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值