2013-05-03 12 views
0

假設一個houses表中有許多字段,相關圖像表和其他3個相關表。我有一個昂貴的查詢,檢索所有houses數據,以及相關表中的所有數據。在分頁的情況下,我是否需要兩次運行相同的昂貴的MySql查詢:一次用於當前結果頁,一次用於獲取記錄總數?如何避免在分頁中運行兩次相同的昂貴的MySql查詢?

我使用服務器端分頁Limit 0,10,並且需要返回房屋總數以及數據。對我來說,運行與count(*)函數相同的昂貴查詢是沒有意義的,僅僅是因爲我限制了分頁結果集。 是否有另一種方式指示MySQL統計整個查詢,但只返回當前的分頁數據?

我希望我的問題是清楚的... 感謝

+0

這可能是這樣嗎? http://stackoverflow.com/questions/818567/mysql-pagination-without-double-querying – barnyr 2013-05-03 10:10:16

回答

0

CFQUERY有一個總記錄變量,它可能是有用的。您還可以使用cfoutput的startrow和maxrows屬性來控制顯示的記錄數量。最後,您可以將查詢結果緩存在ColdFusion中,這樣您就不必每次都在數據庫上運行它。

+0

嗨Dan,感謝您的快速回復 首先,我使用的是由flex客戶端調用的cfc函數,因此cfoutput是這種情況不可能。其次,如果我使用cfquery對象的RecordCount,這意味着我需要理論上選擇10000條記錄的實際數據來計算它,而我仍然需要返回它的10條記錄...... 所以緩存,你的意思是chachWithin?我不確定這一個,因爲每次打電話給服務器可能會使用不同的過濾器讓我們說,房子的大小或面積類型等等...所以我不明白我該如何緩存這種查詢...? ?? – Ajar 2013-05-03 10:27:43

+0

您是否將查詢對象返回給客戶端,還是正在轉換它?無論哪種情況,您都可以使用cfc中的cf功能來傳輸正確數量的數據。 – 2013-05-03 11:46:21

1

我不知道MySql,但對於很多dbs,我認爲你會發現運行兩次的代價並不像你想象的那麼高 - 如果你這樣做的話,數據庫的優化引擎認爲這兩個查詢具有很多共同點。

運行

select count(1) from (
    select some_fields, row_number over (order by field) as rownum 
    from some_table 
) 

然後

select * from (
    select some_fields, row_number over (order by field) as rownum 
    from some_table 
) 
where rownum between :startRow and :endRow 
order by row_number 

這也有你能夠保持查詢在一個地方,周圍有兩個不同的包裝,1尋呼和1的優勢獲得總數。

正如一個側面說明,你可以做的最好的優化是確保你發送完全相同的查詢到數據庫每次。換句話說,如果用戶可以更改排序或更改他們可以查詢的字段,則將其全部燒錄到相同的查詢中。例如:

select some_fields, 
    case 
    when :sortField = 'ID' and :sortType = 'asc' 
     then row_number over (order by id) 
    when :sortField = 'ID' and :sortType = 'desc' 
     then row_number over (order by id desc) 
    end as rownum 
from some_table 
where (:searchType = 'name' 
    and last_name like :lastName and first_name like :firstName) 
or (:searchType = 'customerType' 
    and customer_type = :customer_type) 
+0

這就是我的想法,使用窗口化SQL函數來計算您的「昂貴查詢」。然後把它變成一個瑣碎的東西,只抓取N個記錄或記錄N + 10等。 – 2013-05-03 11:54:37

相關問題