Query takes much to long, is there a work around?

Query takes much to long, is there a work around?

am 04.10.2005 13:55:16 von Toon van Doorn

Hello all,

I made a mailing system where i log al the hits.

The query is dynamic, now there is this mailing with 16 links to log.
Here is the query to get out the data.
#########################
SELECT *,
(SELECT count(linkcode) FROM linklog WHERE linklog.mailcode='24120256' AND
linkcode='1012' AND linklog.adrescode=adreslog.alogid) as Homepage,
(SELECT count(linkcode) FROM linklog WHERE linklog.mailcode='24120256' AND
linkcode='1234' AND linklog.adrescode=adreslog.alogid) as Mickey,
(SELECT count(linkcode) FROM linklog WHERE linklog.mailcode='24120256' AND
linkcode='2345' AND linklog.adrescode=adreslog.alogid) as Winnie,
(SELECT count(linkcode) FROM linklog WHERE linklog.mailcode='24120256' AND
linkcode='3010' AND linklog.adrescode=adreslog.alogid) as Kd,
(SELECT count(linkcode) FROM linklog WHERE linklog.mailcode='24120256' AND
linkcode='3020' AND linklog.adrescode=adreslog.alogid) as Lleft,
(SELECT count(linkcode) FROM linklog WHERE linklog.mailcode='24120256' AND
linkcode='3030' AND linklog.adrescode=adreslog.alogid) as Ergo,
(SELECT count(linkcode) FROM linklog WHERE linklog.mailcode='24120256' AND
linkcode='3040' AND linklog.adrescode=adreslog.alogid) as Optic,
(SELECT count(linkcode) FROM linklog WHERE linklog.mailcode='24120256' AND
linkcode='3050' AND linklog.adrescode=adreslog.alogid) as Mic,
(SELECT count(linkcode) FROM linklog WHERE linklog.mailcode='24120256' AND
linkcode='3060' AND linklog.adrescode=adreslog.alogid) as Toets,
(SELECT count(linkcode) FROM linklog WHERE linklog.mailcode='24120256' AND
linkcode='3070' AND linklog.adrescode=adreslog.alogid) as Kabel,
(SELECT count(linkcode) FROM linklog WHERE linklog.mailcode='24120256' AND
linkcode='3456' AND linklog.adrescode=adreslog.alogid) as Sponge,
(SELECT count(linkcode) FROM linklog WHERE linklog.mailcode='24120256' AND
linkcode='4567' AND linklog.adrescode=adreslog.alogid) as Cookie,
(SELECT count(linkcode) FROM linklog WHERE linklog.mailcode='24120256' AND
linkcode='5678' AND linklog.adrescode=adreslog.alogid) as Dora,
(SELECT count(linkcode) FROM linklog WHERE linklog.mailcode='24120256' AND
linkcode='6789' AND linklog.adrescode=adreslog.alogid) as Cool,
(SELECT count(linkcode) FROM linklog WHERE linklog.mailcode='24120256' AND
linkcode='7891' AND linklog.adrescode=adreslog.alogid) as Col,
(SELECT count(linkcode) FROM linklog WHERE linklog.mailcode='24120256' AND
linkcode='8912' AND linklog.adrescode=adreslog.alogid) as Headset
FROM adreslog WHERE mailcode='24120256'

3599 rows fetched (71,81 sec)
#######################

This way i get the information of the adres and how often they clicked on
wich link.

The explain on this query gives
51 rows fetched (0,19 sec)

Is there a faster way of selecting the hits on a link per adres?

Every hit is a record in the linklog table

CREATE TABLE "public"."linklog" (
"llogid" BIGSERIAL,
"mailcode" VARCHAR(15),
"linkcode" VARCHAR(15),
"adrescode" BIGINT,
"date" TIMESTAMP(6) WITHOUT TIME ZONE
) WITH OIDS;

This is the table with adresses
CREATE TABLE "public"."adreslog" (
"alogid" SERIAL,
"mailcode" VARCHAR(15),
"naam1" VARCHAR(255),
"naam2" VARCHAR(255),
"naam3" VARCHAR(255),
"adres" VARCHAR(70),
"firstread" TIMESTAMP(6) WITHOUT TIME ZONE,
"lastread" TIMESTAMP(6) WITHOUT TIME ZONE,
"totalread" INTEGER DEFAULT 0
) WITH OIDS;

Kind regards,
Toon van Doorn


---------------------------(end of broadcast)---------------------------
TIP 3: Have you checked our extensive FAQ?

http://www.postgresql.org/docs/faq

Re: Query takes much to long, is there a work around?

am 04.10.2005 14:18:47 von Frank Bax

At 07:55 AM 10/4/05, Toon van Doorn wrote:
>Is there a faster way of selecting the hits on a link per adres?


This type of question (slow query) is usually asked on pgsql-sql list, it
has nothing to do with php.

You didn't mention indexes - surely you have indexes on your tables?

Check the output of "EXPLAIN ANALYSE" for one of your "select count ..."
subqueries.

I think your query will benefit from a multi-column index on ( mailcode,
linkcode, adrescode ), but 16 subselects and 51 rows in adreslog means over
800 subqueries being executed - that's a lot of work to do!!

What happens if you change
SELECT count(linkcode) FROM linklog WHERE linklog.mailcode='24120256' AND
linkcode='1012' AND linklog.adrescode=adreslog.alogid) as Homepage
to somthing like:
SELECT adrescode, mailcode, count(linkcode) FROM linklog WHERE
mailcode='24120256' AND
linkcode='1012' as Homepage

then join to adreslog table.


---------------------------(end of broadcast)---------------------------
TIP 3: Have you checked our extensive FAQ?

http://www.postgresql.org/docs/faq

Re: Query takes much to long, is there a work around?

am 04.10.2005 16:46:23 von Toon van Doorn

Found it,

I now use

SELECT adreslog.adres,adreslog.totalread
,sum(case when linkcode='1012' AND linklog.adrescode=adreslog.alogid then 1
else 0 end ) as Homepage
,sum(case when linkcode='1234' AND linklog.adrescode=adreslog.alogid then 1
else 0 end ) as Mickey

FROM adreslog left join linklog on (adreslog.alogid = linklog.adrescode)

WHERE adreslog.mailcode='24120256'
group by adreslog.adres,adreslog.totalread;

Your comment about joining the tables helped.

Thanks !!


Kind regards,
Toon van Doorn


-----Oorspronkelijk bericht-----
Van: pgsql-php-owner@postgresql.org [mailto:pgsql-php-owner@postgresql.org]
Namens Frank Bax
Verzonden: dinsdag 4 oktober 2005 14:19
Aan: pgsql-php@postgresql.org
Onderwerp: Re: [PHP] Query takes much to long, is there a work around?

At 07:55 AM 10/4/05, Toon van Doorn wrote:
>Is there a faster way of selecting the hits on a link per adres?


This type of question (slow query) is usually asked on pgsql-sql list, it
has nothing to do with php.

You didn't mention indexes - surely you have indexes on your tables?

Check the output of "EXPLAIN ANALYSE" for one of your "select count ..."
subqueries.

I think your query will benefit from a multi-column index on ( mailcode,
linkcode, adrescode ), but 16 subselects and 51 rows in adreslog means over
800 subqueries being executed - that's a lot of work to do!!

What happens if you change
SELECT count(linkcode) FROM linklog WHERE linklog.mailcode='24120256' AND
linkcode='1012' AND linklog.adrescode=adreslog.alogid) as Homepage to
somthing like:
SELECT adrescode, mailcode, count(linkcode) FROM linklog WHERE
mailcode='24120256' AND linkcode='1012' as Homepage

then join to adreslog table.


---------------------------(end of broadcast)---------------------------
TIP 3: Have you checked our extensive FAQ?

http://www.postgresql.org/docs/faq


---------------------------(end of broadcast)---------------------------
TIP 9: In versions below 8.0, the planner will ignore your desire to
choose an index scan if your joining column's datatypes do not
match