PHP MySQL分页很慢

c3c*_*ris 5 php mysql pagination

我的桌子

Field   Type    Null    Key Default Extra
id      int(11)     NO  PRI NULL    auto_increment
userid  int(11)     NO  MUL NULL     
title   varchar(50) YES     NULL     
hosting varchar(10) YES     NULL     
zipcode varchar(5)  YES     NULL     
lat     varchar(20) YES     NULL     
long    varchar(20) YES     NULL     
msg    varchar(1000)YES MUL NULL     
time    datetime    NO      NULL     
Run Code Online (Sandbox Code Playgroud)

那是桌子.我已经模拟了500k行数据并随机删除了270k行,只剩下230k,自动增量为500k.

这是我的索引

Keyname Type    Unique  Packed  Field   Cardinality Collation   Null
PRIMARY BTREE   Yes No  id            232377    A       
info    BTREE   No  No  userid          2003    A       
lat                                    25819    A   YES
long                                   25819    A   YES
title                                  25819    A   YES
time                                   25819    A   
Run Code Online (Sandbox Code Playgroud)

考虑到这一点,这是我的查询:

SELECT*FROM postsWHERE long> -118.13902802886 AND long<-118.08130797114 AND lat> 33.79987197114 AND lat<33.85759202886 ORDER BY id ASC LIMIT 0,25

显示行0 - 15(总共16行,查询耗时1.5655秒)[id:32846 - 540342]

该查询只给我带来了1页,但由于它必须搜索所有230k记录,它仍然需要1.5秒.

这是查询解释:

id  select_type table   type    possible_keys   key     key_len ref rows    Extra
1   SIMPLE      posts   index   NULL            PRIMARY 4       NULL 25     Using where
Run Code Online (Sandbox Code Playgroud)

因此,即使我使用where子句只能获得16个结果,我仍然会得到一个缓慢的查询.

现在举例来说,如果我做更广泛的搜索:

SELECT * FROM `posts` WHERE `long`>-118.2544681443 AND `long`<-117.9658678557 AND `lat`>33.6844318557 AND `lat`<33.9730321443 ORDER BY id ASC LIMIT 0, 25
Run Code Online (Sandbox Code Playgroud)

显示行0 - 24(总计25,查询花了0.0849秒)[id:691 - 29818]

从20页中检索第一页时发现速度要快得多,483发现总数,但我限制为25.

但如果我要求最后一页

SELECT * FROM `posts` WHERE `long`>-118.2544681443 AND `long`<-117.9658678557 AND `lat`>33.6844318557 AND `lat`<33.9730321443 ORDER BY id ASC LIMIT 475, 25
Run Code Online (Sandbox Code Playgroud)

显示行0 - 7(总共8行,查询耗时1.5874秒)[id:553198 - 559593]

我得到一个缓慢的查询.

我的问题是如何实现良好的分页?当网站上线时,我预计当它起飞时,每天都会删除数百个帖子.帖子应按ID或时间戳排序,而Id不是连续的,因为某些记录将被删除.我希望有一个标准的分页

1 2 3 4 5 6 7 8 ... [Last Page]
Run Code Online (Sandbox Code Playgroud)

c3c*_*ris 0

我想到了。让我放慢速度的是 order by。因为我会调用一个极限,并且我要求的越低,它必须排序的就越多。所以然后我通过添加一个子查询来修复它,首先使用子句提取我想要的数据,WERE 然后我使用ORDER BYLIMIT

SELECT * FROM 
    (SELECT * from `posts` as `p` 
        WHERE 
           `p`.`long`>-119.2544681443 
           AND `p`.`long`<-117.9658678557 
           AND `p`.`lat`>32.6844318557 A
           ND `p`.`lat`<34.9730321443  

    ) as posttable 
    order by id desc 
    limit x,n
Run Code Online (Sandbox Code Playgroud)

通过这样做,我取得了以下成果:

id  select_type     table        type   possible_keys   key key_len ref     rows    Extra
1   PRIMARY         <derived2>   ALL    NULL            NULL NULL   NULL    3031    Using filesort
2   DERIVED         p            ALL    NULL            NULL NULL   NULL    232377  Using where
Run Code Online (Sandbox Code Playgroud)

现在我使用“where”过滤 232k 个结果,仅 orderby 并限制 3031 个结果。

显示行 0 - 3030(总共 3,031 行,查询花费了 0.1431 秒)