mysql在大数据量的时候如何快速分页/排序

时间:2021-06-30 11:31:41
在mysql大数据量的时候(100万以上甚至更多)
如何有效,快速的分页排序?
比如这样的语句在大数据的时候慢的要死:
SELECT title FROM table WHERE forumid=1 && isshow=1 ORDER BY postdate DESC LIMIT 2000000,20;
在LIMIT 1000000,20的时候运行时间差不多需要1x秒,最坏的时候会有20秒,200万估计更加完蛋.按照这样来做的话超时也说不定.
就算20万的数据用这种方法来做,时间也要3秒多,无法忍受啊.
请教各位高手,mysql在大数据的情况下是如何优化分页与排序的?
谢谢.

19 个解决方案

#1


好问题关注
up

#2


SQL句子这么写,在数据库里查,很难提高效率
但结果不会一次把100w的东西显示给客户吧
应该是根据客户每页的需要limit出数据库

排序尽量用javascript,把符合分到客户端去.

#3


关注一下!

#4


第一次查询的可能会慢些,
这个时候应该将第一次查询到的已排序结果存到一个临时表
那么再次去其他页的时候就不需要再次排序了。

#5


mysql也只能处理100-200万条记录

1、对postdate建立索引
2、按postdate这个名字看,应该是日期类型。那么降序的第2000000应该是很久远的数据了,可以仅凭postdate的值进行过滤,而不必拘泥与每页20条的增量

#6


没有亲身接触这么大的数据库

不过,我想到了这个数量级,慢点也没有办法了.

#7


是啊,大家有什么好的办法吗?

我用如下语句:
SELECT * FROM `db1` where a02 <> "" order by a061 desc LIMIT 1000000 , 30;
竟用了2.x秒
SELECT * FROM `db1` where a02 <> "" order by a061 desc LIMIT 100 , 30;
用:0.005x秒

还有,在一个有十几万条记录中建立index,要十几秒
这数据有没有可能呢?如果是有没有什么好的解决办法?

#8


你不要order by试一下

SELECT * FROM `db1` where a02 <> "" LIMIT 1000000 , 30;

因为如果你order by的话要对前面1000000条记录进行排序,这样延耗时间肯定多

limit 100,30只对前面100条排,


按我前面回的,尽量不要使用order by,用javascript排,把符合分到客户端.

#9


楼主,看样子你对索引并不了解呀。
对一个没有索引的表进行索引,十几秒算是快的。但一旦索引后就由数据库系统维护了。数据库系统会高效的利用索引快速定位到需要的记录

#10


向  xuzuning(唠叨) 同志学习

#11


同意xuzuning(唠叨) 兄
只要适当的建立索引,不会出现楼住的那种情况

#12


1,相关列已经建立索引(pastdate,isshow,forumid)
2,如果不用ORDER BY 确实能提高效率
现在的问题就是:如果有ORDER BY 的话就会慢,但是我希望取的数据是最新的,换句话来说也就是取id值最大的或者postdate值最大的.
分段select是个好办法,但是如果进行分段搜索的话,
where id between min and max && isshow =1  order by  pastdate desc limit 0,10;
如何取得min的值呢?id不连续的.如果MAX-100,划出一个范围,但是这100个里面如果没有isshow=1呢?那,再加大范围,1000,或者百分之几,如果出现没有isshow=1的情况呢?
谢谢楼上所以的人.

#13


to foolfish(呆鱼) :
SELECT * FROM `db1` where a02 <> "" LIMIT 1000000 , 30;
确实,不用order by 之后是快了很多,只用0.5x秒,但是如果就有1000000条合条件的,我又要按照一定的顺序取得其中一定量的内容,如果不用order by ,那是否要把所有合条件的传回,再用js处理呢?

#14


我觉得如果把所有记录全部取出来,再用js来处理的话,数据量小的话可能还可行(如果数据量小的话,不在今天要讨论的话题范围了),但是数据量大的话,看看cpu占用吧.
另外
to Jatic(要学的太多了):
a02<>""
a02不为""的记录不多吧?如果要是where a02=(大数据量记录的),你再试试.很慢.就算你做了index

#15


1、"如果把所有记录全部取出来,再用js来处理。"
  这是最不可取的办法,不到万不可以时最好不要用,大量的数据在网络中传输不是问题也是问题
2、我150万条记录在主频166的服务器上检索大约10秒左右。由于是nt,使用com可使时间下降到2-3秒。当然这与服务器性能有很大的关系,不过现在都是数G的服务器了。
3、按时间降序排列再取2000000条以后的数据,说是“最新的”应该打个问号。

#16


to windbrick(风中的板砖) :
用“<>”与“=”在符合条件记录差不多条件下时间代价差不多。
用order by 的话要慢很多

就是在大量数据时如何实现如 foolfish(呆鱼)所说的js排序

有没有其它好的方法呢?

#17



我以前也想过分段查
可是:
where id between min and max && isshow =1  order by  pastdate desc limit 0,10;
如何取得min的值呢?
1,id不连续的.
2,如何能确定在这个范围内确实有isshow=1并且大于10条的记录呢?
3,搜索范围越大,速度也就越慢

谢谢楼上所以的人.

#18


to:Jatic(要学的太多了)
select title from brick_post where forumid=3 limit 630000,10;(forumid=3的记录有329340条)
查询时间3秒多,将近4秒,不能忍受.
select title from brick_post where forumid=6 limit 630000,10;(forumid=6的记录有7条)
查询时间0.000x
总记录数329352.
这是我测试的结果.

#19


将limit 630000,10改成limit 329000,10

#1


好问题关注
up

#2


SQL句子这么写,在数据库里查,很难提高效率
但结果不会一次把100w的东西显示给客户吧
应该是根据客户每页的需要limit出数据库

排序尽量用javascript,把符合分到客户端去.

#3


关注一下!

#4


第一次查询的可能会慢些,
这个时候应该将第一次查询到的已排序结果存到一个临时表
那么再次去其他页的时候就不需要再次排序了。

#5


mysql也只能处理100-200万条记录

1、对postdate建立索引
2、按postdate这个名字看,应该是日期类型。那么降序的第2000000应该是很久远的数据了,可以仅凭postdate的值进行过滤,而不必拘泥与每页20条的增量

#6


没有亲身接触这么大的数据库

不过,我想到了这个数量级,慢点也没有办法了.

#7


是啊,大家有什么好的办法吗?

我用如下语句:
SELECT * FROM `db1` where a02 <> "" order by a061 desc LIMIT 1000000 , 30;
竟用了2.x秒
SELECT * FROM `db1` where a02 <> "" order by a061 desc LIMIT 100 , 30;
用:0.005x秒

还有,在一个有十几万条记录中建立index,要十几秒
这数据有没有可能呢?如果是有没有什么好的解决办法?

#8


你不要order by试一下

SELECT * FROM `db1` where a02 <> "" LIMIT 1000000 , 30;

因为如果你order by的话要对前面1000000条记录进行排序,这样延耗时间肯定多

limit 100,30只对前面100条排,


按我前面回的,尽量不要使用order by,用javascript排,把符合分到客户端.

#9


楼主,看样子你对索引并不了解呀。
对一个没有索引的表进行索引,十几秒算是快的。但一旦索引后就由数据库系统维护了。数据库系统会高效的利用索引快速定位到需要的记录

#10


向  xuzuning(唠叨) 同志学习

#11


同意xuzuning(唠叨) 兄
只要适当的建立索引,不会出现楼住的那种情况

#12


1,相关列已经建立索引(pastdate,isshow,forumid)
2,如果不用ORDER BY 确实能提高效率
现在的问题就是:如果有ORDER BY 的话就会慢,但是我希望取的数据是最新的,换句话来说也就是取id值最大的或者postdate值最大的.
分段select是个好办法,但是如果进行分段搜索的话,
where id between min and max && isshow =1  order by  pastdate desc limit 0,10;
如何取得min的值呢?id不连续的.如果MAX-100,划出一个范围,但是这100个里面如果没有isshow=1呢?那,再加大范围,1000,或者百分之几,如果出现没有isshow=1的情况呢?
谢谢楼上所以的人.

#13


to foolfish(呆鱼) :
SELECT * FROM `db1` where a02 <> "" LIMIT 1000000 , 30;
确实,不用order by 之后是快了很多,只用0.5x秒,但是如果就有1000000条合条件的,我又要按照一定的顺序取得其中一定量的内容,如果不用order by ,那是否要把所有合条件的传回,再用js处理呢?

#14


我觉得如果把所有记录全部取出来,再用js来处理的话,数据量小的话可能还可行(如果数据量小的话,不在今天要讨论的话题范围了),但是数据量大的话,看看cpu占用吧.
另外
to Jatic(要学的太多了):
a02<>""
a02不为""的记录不多吧?如果要是where a02=(大数据量记录的),你再试试.很慢.就算你做了index

#15


1、"如果把所有记录全部取出来,再用js来处理。"
  这是最不可取的办法,不到万不可以时最好不要用,大量的数据在网络中传输不是问题也是问题
2、我150万条记录在主频166的服务器上检索大约10秒左右。由于是nt,使用com可使时间下降到2-3秒。当然这与服务器性能有很大的关系,不过现在都是数G的服务器了。
3、按时间降序排列再取2000000条以后的数据,说是“最新的”应该打个问号。

#16


to windbrick(风中的板砖) :
用“<>”与“=”在符合条件记录差不多条件下时间代价差不多。
用order by 的话要慢很多

就是在大量数据时如何实现如 foolfish(呆鱼)所说的js排序

有没有其它好的方法呢?

#17



我以前也想过分段查
可是:
where id between min and max && isshow =1  order by  pastdate desc limit 0,10;
如何取得min的值呢?
1,id不连续的.
2,如何能确定在这个范围内确实有isshow=1并且大于10条的记录呢?
3,搜索范围越大,速度也就越慢

谢谢楼上所以的人.

#18


to:Jatic(要学的太多了)
select title from brick_post where forumid=3 limit 630000,10;(forumid=3的记录有329340条)
查询时间3秒多,将近4秒,不能忍受.
select title from brick_post where forumid=6 limit 630000,10;(forumid=6的记录有7条)
查询时间0.000x
总记录数329352.
这是我测试的结果.

#19


将limit 630000,10改成limit 329000,10

#20