2013-05-30 71 views
1

網頁返回樣本行應顯示從PostgreSQL數據庫特定產品類別的一個產品形象。 該圖像應在每25秒後自動更改爲其他圖像。返回的產品可能是隨機的或按某種順序排列的。某些產品可能會丟失,並且一些重複的但標準中的大部分產品都應返回。 當前可用的圖像計數可能樣本檢索之間稍微改變如何從數據庫中逐個

目前以下碼被用於其每25秒後執行。 這需要兩個查詢數據庫:一個用於計數其可slwo和第二對 單個圖像檢索。在兩種情況下,子句都是重複的,在實際應用中,子句非常大,改變它需要在兩個地方進行更改。

如何提高這使單個查詢返回的樣品? 列類型不能更改,使用自然主鍵。如果有幫助,可以添加其他列,觸發器,索引,序列。

ASP.NET/Mono MVC3,Npgsql的被使用。

$count = select count(*) 
     from products 
     where prodtype=$sometype and productid in (select productid from images); 

$random = next random integer between 0 .. $count-1; 

-- $productsample is result: desired sample product 
$productsample = select product 
      from products 
      where prodtype=$sometype and productid in (select productid from images) 
      offset $random 
      limit 1; 


create table products (productid char(20) primary key, 
    prodtype char(10) references producttype 
); 

create table images(
id serial primary key, 
productid char(20) references products, 
mainimage bool 
); 

回答

2

order by永遠是昂貴特別是如果在訂單中表達不被索引。所以不要點菜。相反,在您的查詢中,在count()中做一個隨機偏移量,但一次完成。

with t as (
    select * 
    from 
     products p 
     inner join 
     images i using (productid) 
    where 
     prodtype = $sometype 
) 
select * 
from t 
offset floor(random() * (select count(*) from t)) 
limit 1 

該版本可能更快

with t as (
    select *, count(*) over() total 
    from 
     products p 
     inner join 
     images i using (productid) 
    where 
     prodtype = $sometype 
) 
select * 
from t 
offset floor(random() * (select total from t limit 1)) 
limit 1 
0

PosgreSQL:

SELECT column FROM table 
ORDER BY RANDOM() 
LIMIT 1 

這給了你一個,隨機行。你當然可以加回你的WHERE過濾器,以確保它是正確的類別。

這將刪除你的要求,首先做一個計數;並且還具有讓數據庫引擎執行選擇,減少往返的優點。

注:對於人們在尋找方法在其它SQL引擎要做到這一點:http://www.petefreitag.com/item/466.cfm

+0

謝謝。答案中的鏈接描述這很昂貴:它將檢索所有行並在內存中排序。如果這是PostgreSql中最有效的方法? – Andrus

相關問題