Thread
-
Re: How to speed up product code and subcode match
Andrus <kobruleht2@hot.ee> — 2023-05-23T13:38:30Z
Hi! I ran analyze toode; create index vordlusajuhinnak_toode_pattern_idx on vordlusajuhinnak(toode bpchar_pattern_ops); create index vordlusajuhinnak_toode_idx on vordlusajuhinnak(toode); analyze vordlusajuhinnak; Select runs now more than one hour. Output from explain explain create table peatoode as select toode.toode , n2, n3, n4 from toode, vordlusajuhinnak WHERE toode.toode=vordlusajuhinnak.toode OR toode.toode LIKE vordlusajuhinnak.toode||'/%' "Gather (cost=1000.55..443361894.55 rows=143828910 width=78)" " Workers Planned: 2" " -> Nested Loop (cost=0.55..428978003.55 rows=59928712 width=78)" " Join Filter: ((toode.toode = (vordlusajuhinnak.toode)::bpchar) OR (toode.toode ~~ ((vordlusajuhinnak.toode)::text || '/%'::text)))" " -> Parallel Index Only Scan using toode_pkey on toode (cost=0.55..95017.93 rows=303869 width=60)" " -> Seq Scan on vordlusajuhinnak (cost=0.00..721.33 rows=39433 width=32)" with Set enable_nestloop to off; explain output is: "Gather (cost=10000001000.55..10443361906.55 rows=143828910 width=78)" " Workers Planned: 2" " -> Nested Loop (cost=10000000000.55..10428978015.55 rows=59928712 width=78)" " Join Filter: ((toode.toode = (vordlusajuhinnak.toode)::bpchar) OR (toode.toode ~~ ((vordlusajuhinnak.toode)::text || '/%'::text)))" " -> Parallel Index Only Scan using toode_pkey on toode (cost=0.55..95029.93 rows=303869 width=60)" " -> Seq Scan on vordlusajuhinnak (cost=0.00..721.33 rows=39433 width=32)" How to speed it up? Andrus. 23.05.2023 14:32 Bzm@g kirjutas: > Great, > > However I think it is still way to slow. > Next step is to run analyze also for the other table vordlusajuhinnak. > > And make sure you have an index on vordlusajuhinnak.toode similar to > the index on toode.toode > > -- > Boris > > >> Am 23.05.2023 um 12:56 schrieb Andrus <kobruleht2@hot.ee>: >> >> >> >> Hi! >> >> I ran analyze firma2.toode and changed where clause to use like: >> >> create table peatoode as >> select toode.toode , n2, n3, n4 >> from toode, vordlusajuhinnak >> WHERE toode.toode=vordlusajuhinnak.toode OR toode.toode LIKE >> vordlusajuhinnak.toode||'/%' >> >> In this case it took 37 minutes, returned 277966 rows. >> >> Thank you for help. >> >> Andrus. >> >> 23.05.2023 11:24 Bzm@g kirjutas: >>> Also your row count is way off I guess. Did you ever run analyze bigtable? >>> >>> -- >>> Boris >>> >>> >>>> Am 23.05.2023 um 10:22 schriebbzm@2bz.de: >>>> >>>> Hi there, >>>> >>>> I guess the main problem is the nested loop. >>>> >>>> As a quick recheck what happened if you run your query Without nested loop? >>>> >>>> This is not a solution but a quickt test >>>> >>>> In a Session >>>> >>>> Set enable_nestedloop = off; >>>> Explain Select your query ; >>>> -- >>>> Boris >>>> >>>> >>>>> Am 23.05.2023 um 08:53 schrieb Andrus<kobruleht2@hot.ee>: >>>>> >>>>> Hi! >>>>> >>>>> Price list of main products vordlusajuhinnak contains 3 prices for product (column toode) and has 39433 products: >>>>> >>>>> create table vordlusajuhinnak( toode varchar(60), n2 numeric(8,2), n3 numeric(8,2), n4 numeric(8,2) ); >>>>> >>>>> toode column in unique, may be primary key in table and contains upper case letters, digits and - characters. >>>>> >>>>> product table (toode) contains 733021 products: >>>>> >>>>> CREATE TABLE toode ( >>>>> grupp character(1), >>>>> toode character(60) primary key, >>>>> ... lot of other columns >>>>> ); >>>>> >>>>> Both tables have pattern indexes to speed up queries: >>>>> >>>>> CREATE INDEX toode_toode_pattern_idx >>>>> ON toode (toode bpchar_pattern_ops ASC NULLS LAST); >>>>> -- This index is probably not used, should removed: >>>>> CREATE INDEX vordlusajuhinnak_toode_pattern_idx ON vordlusajuhinnak(toode bpchar_pattern_ops); >>>>> >>>>> Product table as both main products and subproducts with sizes. Size is separated by main product code always by / character: >>>>> >>>>> >>>>> SHOE1-BLACK >>>>> SHOE1-BLACK/38 >>>>> SHOE1-BLACK/41 >>>>> SHOE1-BLACK/42 >>>>> SHOE1-BLACK/43 >>>>> SHOE2/XXL >>>>> SHOE2/L >>>>> >>>>> Product codes contain upper characers only in this table also. >>>>> >>>>> Trying to get prices for all products using >>>>> >>>>> create table peatoode as >>>>> select toode.toode , n2, n3, n4 >>>>> from toode, vordlusajuhinnak >>>>> where toode.toode between vordlusajuhinnak.toode and vordlusajuhinnak.toode||'/z' >>>>> >>>>> Takes 4.65 hours. How to speed this query up? >>>>> Output from explain: >>>>> >>>>>> "Nested Loop (cost=0.55..272273178.12 rows=3202240012 width=78)"" >>>>>> -> Seq Scan on vordlusajuhinnak (cost=0.00..721.33 rows=39433 width=32)" " -> Index Only Scan using toode_pkey on toode >>>>>> (cost=0.55..6092.62 rows=81207 width=60)" " Index Cond: (toode >>>>>>> = (vordlusajuhinnak.toode)::bpchar)" " Filter: ((toode)::text <= ((vordlusajuhinnak.toode)::text || '/z'::text))" >>>>> Using PostgreSQL 13.2, compiled by Visual C++ build 1900, 64-bit in Windows server and psqlODBC driver. >>>>> Upgrading Postgres is possible, if this helps. >>>>> >>>>> Tried also using like: >>>>> >>>>> WHERE toode.toode=vordlusajuhinnak.toode OR >>>>> toode.toode LIKE vordlusajuhinnak.toode||'/%' >>>>> >>>>> Posted also in >>>>> >>>>> https://stackoverflow.com/questions/76311957/how-to-match-character-columns-with-separated-subcolumns >>>>> >>>>> Andrus. >>>>> >>>>> >>>>>