2014-07-24 97 views
0

我们正在将我们的应用程序之一从PostgreSQL迁移到MySQL。我们在POSTGRES下面的查询 -统计数据库中的记录总数,但只返回X记录

SELECT 
     idrte 
    , left_name 
    , gacodemun 
    , clsrte 
    , speed 
    , speed_override 
    , ST_AsGeoJSON(geometry) AS geometry 
    , count(idrte) OVER() AS total 
FROM 
    aq_routes 
WHERE 
    ST_CONTAINS(
     GeomFromText(
      'Polygon(($geom))' 
     ),geometry) 
GROUP BY 
     idrte 
    , left_name 
    , gacodemun 
    , clsrte 
    , speed 
    , speed_override 
    , geometry 
ORDER BY left_name 
LIMIT 150; 

我们正试图端口此查询MySQL的广告都拿出了这一点 -

SELECT 
    id AS id 
    , left_name AS left_name 
    , left_locality AS left_locality 
    , class AS class 
    , speed AS speed 
    , speed_override AS speed_override 
    , AsWKB(Geom) AS geom 
    , count(id) AS total 
FROM road_segments 
WHERE 
    CONTAINS(
     GeomFromText(
      'Polygon(($geom))' 
     ),geom) 
GROUP BY 
     id 
    , left_name 
    , class 
    , speed 
    , speed_override 
    , geom 
ORDER BY left_name 
LIMIT 150; 

有一些领域的变化,但对整个预期的功能是相同的。

你会注意到在PostGreSQL中调用OVER()。我们查询的表格有很多数据。因此,对于用户,我们只显示150条记录,但告诉他所有记录的数量。有了PostGres,通过一次调用就可以实现,但我们在MySQL中没有OVER()函数。

除了第二次查询数据库之外,我们还有其他的选择。对数据库的第二个查询是将响应时间增加至少15秒,有时甚至超时。

回答

2

我想你想使用FOUND_ROWS()CALC_FOUND_ROWS()。您可以查阅文档here

的基本思路是:

select CALC_FOUND_ROWS id, . . . 
. . . 

然后使用功能FOUND_ROWS()的值返回给应用程序。

不幸的是,要获得这个值作为列值,我想你需要运行两次查询,主要有:

select . . ., x.cnt 
from . . . cross join 
    (select count(*) as cnt from <your query here>) x 
. . . 
+0

'SELECT SQL_CALC_FOUND_ROWS ...'得到的结果在一个查询的一种方式(使用支持多个结果集的客户端)将两个查询包装在存储过程中。我有一个我使用的接受“每页行数”和“页码”作为参数,为你做数学运算,以便设置限制和偏移量,并返回第二个结果集的总行数,并做一些可爱的含糖计算告诉应用程序什么“页码”是第一个(当然总是1),前一个,当前,下一个和最后一个。 –