如何提高MySQL Limit查询性能的方法详解
在MySQL数据库操作中,我们在做一些查询的时候总希望能避免数据库引擎做全表扫描,因为全表扫描时间长,而且其中大部分扫描对客户端而言是没有意义的。其实我们可以使用Limit关键字来避免全表扫描的情况,从而提高效率。
有个几千万条记录的表onMySQL5.0.x,现在要读出其中几十万万条左右的记录。常用方法,依次循环:
select*frommytablewhereindex_col=xxxlimitoffset,limit;
经验:如果没有blob/text字段,单行记录比较小,可以把limit设大点,会加快速度。
问题:头几万条读取很快,但是速度呈线性下降,同时mysqlservercpu99%,速度不可接受。
调用explainselect*frommytablewhereindex_col=xxxlimitoffset,limit;显示type=ALL
在MySQLoptimization的文档写到"All"的解释
Afulltablescanisdoneforeachcombinationofrowsfromtheprevioustables.Thisisnormallynotgoodifthetableisthefirsttablenotmarkedconst,andusuallyverybadinallothercases.Normally,youcanavoidALLbyaddingindexesthatallowrowretrievalfromthetablebasedonconstantvaluesorcolumnvaluesfromearliertables.
看样子对于all,mysql就使用比较笨的方法,那就改用range方式?因为id是递增的,也很好修改sql。
select*frommytablewhereid>offsetandidexplain显示type=range,结果速度非常理想,返回结果快了几十倍。
Limit语法:
SELECT*FROMtableLIMIT[offset,]rows|rowsOFFSEToffsetLIMIT子句可以被用于强制SELECT语句返回指定的记录数。LIMIT接受一个或两个数字参数。参数必须是一个整数常量。
如果给定两个参数,第一个参数指定第一个返回记录行的偏移量,第二个参数指定返回记录行的最大数目。初始记录行的偏移量是0(而不是1)。
为了与PostgreSQL兼容,MySQL也支持句法:LIMIT#OFFSET#。
mysql>SELECT*FROMtableLIMIT5,10;//检索记录行6-15 //为了检索从某一个偏移量到记录集的结束所有的记录行,可以指定第二个参数为-1 mysql>SELECT*FROMtableLIMIT95,-1;//检索记录行96-last //如果只给定一个参数,它表示返回最大的记录行数目,换句话说,LIMITn等价于LIMIT0,n mysql>SELECT*FROMtableLIMIT5;//检索前5个记录行MySQL的limit给分页带来了极大的方便,但数据量一大的时候,limit的性能就急剧下降。同样是取10条数据,下面两句就不是一个数量级别的。
select*fromtablelimit10000,10 select*fromtablelimit0,10文中不是直接使用limit,而是首先获取到offset的id然后直接使用limitsize来获取数据。根据他的数据,明显要好于直接使用limit。
这里我具体使用数据分两种情况进行测试。
1、offset比较小的时候:
select*fromtablelimit10,10 //多次运行,时间保持在0.0004-0.0005之间 Select*FromtableWherevid>=(SelectvidFromtableOrderByvidlimit10,1)limit10 //多次运行,时间保持在0.0005-0.0006之间,主要是0.0006结论:偏移offset较小的时候,直接使用limit较优。这个显然是子查询的原因。
2、offset大的时候:
select*fromtablelimit10000,10 //多次运行,时间保持在0.0187左右 Select*FromtableWherevid>=(SelectvidFromtableOrderByvidlimit10000,1)limit10 //多次运行,时间保持在0.0061左右,只有前者的1/3。可以预计offset越大,后者越优。总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对毛票票的支持。如果你想了解更多相关内容请查看下面相关链接