2012-11-06 54 views
0

下面的Java Hibernate的常量是我有一個休眠的SQL查詢的原始內容:在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運行速度不夠快,但正如你可能已經注意到有一個大的,現在( )-1應該是NOW() - INTERVAL 1天。

我修改了嵌套的select語句如下:

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

的修復程序。結果方面工作得很好,但是查詢減慢大規模(幾乎幾乎是一瞬間高達幾秒鐘)。我相信這是因爲DATE(NOW() - INTERVAL 1 DAY)正在被評估很多次(我們有一個非常大的數據集)。我將如何去分離這個計算,以便它只發生一次,而不必從國家,城市,限制等java代碼傳入?

我對hibernate或SQL有很少的經驗,並且我已經嘗試在select語句之前將計算分隔到一個變量中,而不是允許的。我也嘗試對SQL查詢做一些小的修改,但是我一直在收到運行時錯誤,可能是由於SQL無效。

我該怎麼做呢?

謝謝。

回答

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 

EDITED - 新建答案。

我的事情你不需要改變INTERVAL 1 DAY,你堅持到以前的查詢,但與86400000等於更換1INTERVAL 1 DAY(24 * 60 * 60 * 1000)

新的查詢會是什麼樣子

FROM (SELECT * FROM b WHERE first_date > (NOW() - 86400000) 
       AND origin = :countryOfOrigin LIMIT :limit) AS bb 
+0

謝謝你的回覆,我會記住這些變化。你會如何推薦我將 - INTERVAL 1 DAY加快速度?查詢實際上運行速度非常快,DATE(NOW() - 1),這只是INTERVAL業務,它可以極大地減緩 – Tom

+0

您可以使用NOW() - (24 * 60 * 60 * 1000)按日期。或者你可以使用'(NOW() - INTERVAL 1 DAY)'它會返回你已經'date'。所以不需要轉換。 –

+0

我嘗試了你的建議,並沒有提高速度。數學計算與使用INTERVAL 1 DAY相同,並將一些條件置入第一個選擇不會影響速度。我原來的問題問是否有任何方法來分開計算,所以它只在當前的SQL查詢中運行一次 – Tom