Обсуждение: selecting a random record
Any suggestions on how to select a random record from any given table? Culley __________________________________________________ Do You Yahoo!? Yahoo! Auctions - Buy the things you want at great prices. http://auctions.yahoo.com/
Greetings.
I have a smallish sized database that's getting alot of update transactions
to it. It's been running fine over the past several weeks, but suddenly I'm
starting to see :
NOTICE: Deadlock detected -- See the lock(l) manual page for a possible cause.
NOTICE: current transaction is aborted, queries ignored until end of transaction block
NOTICE: current transaction is aborted, queries ignored until end of transaction block
NOTICE: current transaction is aborted, queries ignored until end of transaction block
NOTICE: Deadlock detected -- See the lock(l) manual page for a possible cause.
appear in my apache error logs from my PHP statements. At the same time the
following messagse appear in Postgres logs :
NOTICE: Deadlock detected -- See the lock(l) manual page for a possible cause.
ERROR: WaitOnLock: error on wakeup - Aborting this transaction
DEBUG: Last error occured while executing PL/pgSQL function add_impression
DEBUG: line 16 at SQL statement
NOTICE: current transaction is aborted, queries ignored until end of transaction block
NOTICE: current transaction is aborted, queries ignored until end of transaction block
This is PostgreSQL 7.0.3 running on a Debian Stable system. All
transactions to the database are via PHP 4.0.4pl1 under Apache 1.3.17. I've
made no modifications to the system itself for several weeks (outside of
upgrading apache) and it was running fine under similiar loads in the past.
Any suggestions one how I can rectify this situation would be appriecated. :)
For reference, the function in question is declared as :
CREATE function add_impression( int4, int4, text ) RETURNS int4 AS '
DECLARE
tempvar record;
linkidx ALIAS FOR $1;
linkcat ALIAS FOR $2;
linkloc ALIAS FOR $3;
BEGIN
SELECT INTO tempvar *
FROM linkdaystatsdetail
WHERE linkid = linkidx
AND categorynumber = linkcat
AND location = linkloc;
IF FOUND THEN
UPDATE linkoverviewstatsdetail
SET impressions=impressions+1
WHERE linkid = linkidx
AND categorynumber = linkcat
AND location = linkloc;
ELSE
INSERT INTO linkoverviewstatsdetail ( linkid, categorynumber, location, clicks, impressions )
VALUES ( linkidx, linkcat, linkloc, 0, 1 );
END IF;
UPDATE linkoverviewstats
SET impressions=impressions+1
WHERE linkid = linkidx;
SELECT INTO tempvar *
FROM linkdaystatsdetail
WHERE linkid = linkidx
AND categorynumber = linkcat
AND location = linkloc;
IF FOUND THEN
UPDATE linkdaystatsdetail
SET impressions=impressions+1
WHERE linkid = linkidx
AND categorynumber = linkcat
AND location = linkloc;
ELSE
INSERT INTO linkdaystatsdetail ( linkid, categorynumber, location, clicks, impressions )
VALUES ( linkidx, linkcat, linkloc, 0, 1 );
END IF;
UPDATE linkdaystats
SET impressions=impressions+1
WHERE linkid = linkidx;
RETURN 1;
END;
' LANGUAGE 'PLPGSQL';
linkoverviewstatsdetail and linkdaystatsdetail are very similiar in composition, the schema being :
freehost=# \d linkdaystatsdetail
Table "linkdaystatsdetail"
Attribute | Type | Modifier
----------------+------------+----------
linkid | integer |
categorynumber | integer |
location | varchar(1) |
clicks | integer |
impressions | integer |
Indices: linkdaystatsdetail_linkid_idx,
linkdsd_linkid_cat_loc_idx
freehost=# \d linkdsd_linkid_cat_loc_idx
Index "linkdsd_linkid_cat_loc_idx"
Attribute | Type
----------------+------------
linkid | integer
categorynumber | integer
location | varchar(1)
btree
freehost=# \d linkdaystatsdetail_linkid_idx
Index "linkdaystatsdetail_linkid_idx"
Attribute | Type
-----------+---------
linkid | integer
btree
Thanks in advance,
Sincerely, Warren
Can this be done in the framework of plpgsql? I know I can do it in the front end (java) but it would be nice to aviod having to grab the rowcount first. I haven't seen a random function in the documentation. I could install another language but boy am I lazy :) --- Mark Lane <mlane@mynewthing.com> wrote: > On Tuesday 06 February 2001 13:11, you wrote: > > Any suggestions on how to select a random record > from > > any given table? > > > > Culley > > > Set the range of the table index to a random number > generator. > > if the index ranges from 100 to 10000 then you would > multiply you random > number by 9900 and then 100 to generate a random > index number. Just remember > to round the number to an integer. > > Mark __________________________________________________ Do You Yahoo!? Yahoo! Auctions - Buy the things you want at great prices. http://auctions.yahoo.com/
Warren Vanichuk <pyber@street-light.com> writes:
> I have a smallish sized database that's getting alot of update transactions
> to it. It's been running fine over the past several weeks, but suddenly I'm
> starting to see :
> NOTICE: Deadlock detected -- See the lock(l) manual page for a possible cause.
You've probably added another function that updates the same rows in a
different, conflicting order. For example, suppose you have two
transactions, one of which does
UPDATE table SET f1 = 42 WHERE id = 'foo';
while the other is doing
UPDATE table SET f1 = 23 WHERE id = 'bar';
This is fine, but now suppose the first one does
UPDATE table SET f2 = 11 WHERE id = 'bar';
It's got to wait to see if the second one commits or not, to know which
version of the 'bar' row is relevant and should be updated. Finally,
suppose the second transaction does
UPDATE table SET f2 = 22 WHERE id = 'foo';
Now you have two transactions waiting for each other --- ie, deadlock.
regards, tom lane
> Warren Vanichuk <pyber@street-light.com> writes: > > I have a smallish sized database that's getting alot of update transactions > > to it. It's been running fine over the past several weeks, but suddenly I'm > > starting to see : > > > NOTICE: Deadlock detected -- See the lock(l) manual page for a possible cause. > > You've probably added another function that updates the same rows in a > different, conflicting order. For example, suppose you have two > transactions, one of which does > > UPDATE table SET f1 = 42 WHERE id = 'foo'; > > while the other is doing > > UPDATE table SET f1 = 23 WHERE id = 'bar'; > > This is fine, but now suppose the first one does > > UPDATE table SET f2 = 11 WHERE id = 'bar'; > > It's got to wait to see if the second one commits or not, to know which > version of the 'bar' row is relevant and should be updated. Finally, > suppose the second transaction does > > UPDATE table SET f2 = 22 WHERE id = 'foo'; > > Now you have two transactions waiting for each other --- ie, deadlock. Hrmm. There are only two functions that affect those tables. The add_impressions does a : update table set f1+1 where f3 = 'foo' and f4 = 'bar' and f5 = 'baz'; The add_click does a : update table set f2+1 where f3 = 'foo' and f4 = 'bar' and f5 = 'baz'; All transactions are inside a BEGIN/COMMIT block. You are saying that will be cause the issue that I have been seeing? If so, how exactly does one work around this, given that I need real-time or near real-time reporting of the data collected by these functions... Sincerely, Warren
Greetings, Culley!
At 06.02.2001, 13:11, you wrote:
CH> Any suggestions on how to select a random record from
CH> any given table?
SELECT * FROM any_given_table ORDER BY random() LIMIT 1;
--
Yours, Alexey V. Borzov, Webmaster of RDW
Hi
I dont know exactly why u need this but this can be done in MySQL/PERL
create a file called random.pl
i select a random reecord from Temp table with PK temp_id
#! /usr/bin/perl -w
use Mysql;
$i = (10*rand())%10;
$dbh = Mysql->Connect('localhost','DBNAME','root');
$sth = $dbh->Query("Select * from Temp");
$no = $dbh->Query("Select COUNT(temp_id) from Temp");
@nr = $sth->FetchRow;
for($n=0; $n<@nr[0]; $n++)
{
@row = $sth->FetchRow;
if($n == $i)
{
print @row;
}
}
On Tue, 6 Feb 2001, Culley Harrelson wrote:
> Any suggestions on how to select a random record from
> any given table?
>
> Culley
>
> __________________________________________________
> Do You Yahoo!?
> Yahoo! Auctions - Buy the things you want at great prices.
> http://auctions.yahoo.com/
>