sqlalchemy使用count時遇到的坑

在用flask-sqlalchemy對一個千萬級別表進行count操做時,出現了耗時嚴重、內存飆升的狀況。
要統計出一天內車輛訪問次數,原代碼以下:sql

car_visit_counts = CarVisit.query.filter(
    CarVisit.park == car_visit.park,
    CarVisit.plate_number == car_visit.plate_number,
    CarVisit.visited_at >= today_start_time(),
).count()

發現代碼運行特別慢,因此把生成的sql打印出來看一下:flask

SELECT
          COUNT(*) AS count_1
FROM
          (
                    SELECT
                              car_visits.id                            AS car_visits_id
                            , car_visits.park_id                       AS car_visits_park_id
                            , car_visits.store_id                      AS car_visits_store_id
                            , car_visits.car_id                        AS car_visits_car_id
                            , car_visits.brand_id                      AS car_visits_brand_id
                            , 
                            ...
                    FROM
                              car_visits
                    WHERE
                              %(param_1)s                 = car_visits.park_id
                              AND car_visits.plate_number = %(plate_number_1)s
                              AND car_visits.visited_at  >= %(visited_at_1)s
          )
          AS anon_1

能夠發現進行了一次子查詢,這樣的話會生成臨時表,效率低下,將原語句改變一下:session

car_visit_counts = db.session.query(func.count(CarVisit.id)).filter(
    CarVisit.park == car_visit.park,
    CarVisit.plate_number == car_visit.plate_number,
    CarVisit.visited_at >= today_start_time(),
).scalar()

此時在看一下打印的sql語句:scala

SELECT
          COUNT(car_visits.id) AS count_1
FROM
          car_visits
WHERE
          %(param_1)s                 = car_visits.park_id
          AND car_visits.plate_number = %(plate_number_1)s
          AND car_visits.visited_at  >= %(visited_at_1)s

子查詢消失了,速度也快了好多。code

相關文章
相關標籤/搜索