1

Web ページには、PostgreSql データベースから特定の製品カテゴリの製品イメージを 1 つ表示する必要があります。この画像は、25 秒ごとに別の画像に自動的に変更されます。返品される製品は、ランダムまたはある順序である場合があります。一部の製品が欠落しており、一部が繰り返されている可能性がありますが、基準内のほとんどの製品は返品されます。利用可能な画像の合計数は、サンプル取得ごとにわずかに異なる場合があります

現在、25 秒ごとに実行される以下のコードが使用されています。これには、データベースへの 2 つのクエリが必要です。句が重複している両方のケースで、句が非常に大きく、それを変更する実際のアプリケーションでは、2 つの場所で変更が必要です。

単一のクエリが sample を返すようにこれを改善するにはどうすればよいですか? 列の型は変更できません。自然主キーが使用されます。これが役立つ場合は、追加の列、トリガー、インデックス、シーケンスを追加できます。

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
);
4

2 に答える 2

2

order by の式がインデックス化されていない場合、 anorder byは常に特別に高価になります。だから注文しないでください。代わりに、クエリの as でランダムなオフセットを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
于 2013-05-30T17:46:47.227 に答える
0

PosgreSQL:

SELECT column FROM table
ORDER BY RANDOM()
LIMIT 1

これにより、1 つのランダムな行が得られます。もちろん、WHERE フィルターに再度追加して、それが正しいカテゴリであることを確認することもできます。

これにより、最初にカウントを行う必要がなくなります。また、データベース エンジンに選択を任せることで、ラウンド トリップを削減できるという利点もあります。

注:他の SQL エンジンでこれを行う方法を検討している場合: http://www.petefreitag.com/item/466.cfm

于 2013-05-30T16:01:08.300 に答える