0

以下は、私が持っている休止状態の SQL クエリの元の内容です。

<sql-query name="countryOfOrigin-limit-country-city-location">
<return alias="rb" class="RecentBooking"/>
    SELECT 
        bb.reserv_num as {rb.reservNum}, 
        bb.origin as {rb.countryOfOrigin}, 
        bb.pick_up_loc as {rb.locationId}, 
        bb.first_date as {rb.bookingDate}, 
        bb.pick_up_time as {rb.pickUpDate}, 
        bb.drop_off_time as {rb.dropOffDate},  
        bb.car_price as {rb.carPrice}, 
        bb.discount as {rb.discount}, 
        bb.exchange_rate as {rb.exchangeRate},
        SUBSTRING(a.internal_class,1,1)as {rb.carClass},
        a.car_type as {rb.carType}, 
        bb.vehicle_type as {rb.vehicleType}, 
        s.name as {rb.supplier}, 
        vv.country as {rb.country}, 
        vv.city as {rb.city}, 
        vv.location as {rb.location}, 
        bb.cur as {rb.currency}, 
        a.pics as {rb.carImage}
    FROM (SELECT * FROM b  WHERE first_date > DATE(NOW()-1)AS bb  
    JOIN a a ON a.id = bb.car_id
    JOIN d  d ON d.id = bb.pick_up_loc
    JOIN supplier s ON s.id = d.supplier_id
    JOIN v_location_trans vv ON vv.location_id = d.location_id
    AND vv.lang=33
    AND vv.country = :country
    AND vv.city = :city
    AND vv.location = :location
    AND bb.origin = :countryOfOrigin
    ORDER BY bb.id DESC
    LIMIT :limit
</sql-query>

SQL は十分に高速に実行されますが、お気付きかもしれませんが、NOW()-1 は NOW() - INTERVAL 1 DAY である必要があります。

ネストされた select ステートメントを次のように変更しました。

FROM (SELECT * FROM b WHERE first_date > DATE(NOW() - INTERVAL 1 DAY)) AS bb

この修正は結果に関してはうまく機能しますが、クエリは大幅に遅くなります (数秒までほとんど瞬時に)。

これは、 DATE(NOW() - INTERVAL 1 DAY) が何度も評価されているためだと思います(非常に大きなデータセットがあります)。国、都市、制限などのJavaコードから渡さなくても、この計算が1回だけ発生するように、この計算を分離するにはどうすればよいですか?

私は休止状態または SQL の経験がほとんどなく、select ステートメントの前に計算を変数に分離しようとしましたが、これは許可されていません。また、SQL クエリに小さな変更を加えようとしましたが、おそらく無効な SQL が原因で、実行時エラーが発生し続けます。

どうすればこれを行うことができますか?

ありがとう。

4

1 に答える 1

0

bbレコード全体に対するクエリで新しい一時テーブルを作成しています。

一時テーブルを作成する際に結果を除外することをお勧めします。

たとえば、一時テーブルの作成中に AND 句を配置した場合

AND bb.origin = :countryOfOrigin

お気に入り:

FROM (SELECT * FROM b  WHERE first_date > (NOW() - INTERVAL 1 DAY) AND origin = :countryOfOrigin)AS bb 

また、制限をかけることもできます。

FROM (SELECT * FROM b  WHERE first_date > (NOW() - INTERVAL 1 DAY) AND origin = :countryOfOrigin LIMIT :limit)AS bb 

編集済み- 新しい回答。

を変更する必要はありませんINTERVAL 1 DAY。前のクエリに固執しますが、1を(24*60*60*1000)86400000に置き換えます。INTERVAL 1 DAY

新しいクエリは次のようになります

FROM (SELECT * FROM b WHERE first_date > (NOW() - 86400000) 
               AND origin = :countryOfOrigin LIMIT :limit) AS bb
于 2012-11-06T10:16:58.857 に答える