Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1t0nZd-00DFhQ-4W for pgsql-general@arkaria.postgresql.org; Tue, 15 Oct 2024 19:51:17 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.94.2) (envelope-from ) id 1t0nZZ-00AjnE-1S for pgsql-general@arkaria.postgresql.org; Tue, 15 Oct 2024 19:51:13 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1t0nZY-00Ajn2-Gt for pgsql-general@lists.postgresql.org; Tue, 15 Oct 2024 19:51:13 +0000 Received: from mail-ed1-x544.google.com ([2a00:1450:4864:20::544]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.94.2) (envelope-from ) id 1t0nZV-0013T1-MV for pgsql-general@postgresql.org; Tue, 15 Oct 2024 19:51:11 +0000 Received: by mail-ed1-x544.google.com with SMTP id 4fb4d7f45d1cf-5c97cc837c3so3487473a12.0 for ; Tue, 15 Oct 2024 12:51:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1729021867; x=1729626667; darn=postgresql.org; h=to:subject:message-id:date:from:mime-version:from:to:cc:subject :date:message-id:reply-to; bh=jnLUoFfdZbtSW2Q5J+2x0J/YBS9phfQyUe7uqzDgGxI=; b=CXkiYAo0edXRB2HG/StPduwDELemPC8q4p7acOTlu6WRdDVrLxqsDX5NiBbUS3v6Jv 7mjDAdgOQVX+NMJWZyxJGWsgKB+8eYY6DuEZXE/SVx3/KWc1esKPvGmj2LTTS66jk6mR j7cTmd7AqnQ7t3Uq9PHYiSZ3aFgU+1LqqlPsX0lzMWAN0jISl3aECq5oGybPd+LcfDxw eOlmCikAAmUenpEEILyCr4iuqm6+cooci4Fw33JTL67rjrr3qFzXBdRlLthJf2Vm9ZNQ mA1K/OLbA+4X/YRx9uWffgvy+ymrsHop4Eii1c9s3cY9qrXh6huWWJKL2CgL+twRr1kY kZew== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1729021867; x=1729626667; h=to:subject:message-id:date:from:mime-version:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=jnLUoFfdZbtSW2Q5J+2x0J/YBS9phfQyUe7uqzDgGxI=; b=OFhveYm5xCG2FOPUnrAe2PjDRP27TwPTOfT04wWdBO+WQlGUWWWTLWndowp38CeOAJ +4oT8b5OSutyyoA7mCbVqXXtRjw1iUdd6S89HOijcSj+yX1jEDREGRtsONbGFoVFTOAj mXNvr43QqALgaNBlYFm/MeJHCFJTS+K3td9UmuihcZtSeRuOoSYEnCYoQ6zDpVo6EPOR S/4XgMaE5k/430Z4aUvKqP/5EpLuMxHyrXpzBSu0RZY5983aiPD7X9Kw5EFUUbnOE55W 0BWBtxPiWDqgPTDMyd0rIXJ6WiTnKKGALm/p4//Io31BgRCLIiEYAzyiPZgC/0DrtLcI QG5g== X-Gm-Message-State: AOJu0YwKHcu69KEfOKm+N90lx8TzcDVl4YKZ/U3HtYh8BS4Z93elcfs5 CtoSGX/KUY0xQ9wDOd9FvWLj5whIrxDEe5+U+f+e/pEt8ovX87Qq+Y4fBwjeRKZBv16gZl0Nu70 ubJFqah/jobVf2ai88UovRPE/0CJuH7JQvgI= X-Google-Smtp-Source: AGHT+IEkphS/w37PWzGbZMg0eyJDSyyayXD6FHzjIEaQ54+oDmNB+EYMn6PvXVzZwTLt6dsq3xeFqtEP9VMzDoi9DJw= X-Received: by 2002:a05:6402:5c9:b0:5c8:a0fd:63d6 with SMTP id 4fb4d7f45d1cf-5c948d24835mr13245670a12.20.1729021866536; Tue, 15 Oct 2024 12:51:06 -0700 (PDT) MIME-Version: 1.0 From: Vijaykumar Jain Date: Wed, 16 Oct 2024 01:20:56 +0530 Message-ID: Subject: how to know if the sql will run a seq scan To: pgsql-general Content-Type: multipart/alternative; boundary="00000000000029fc4a0624894661" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --00000000000029fc4a0624894661 Content-Type: text/plain; charset="UTF-8" Hi, tl;dr I am trying to learn what sql can result in a full seq scan. Basically there is a lot of info on the internet of what ddl change may take an access exclusive lock while running a seq scan and hold for long. And for some cases we can make use of "not valid" constraint and then run a validate constraint as work arounds to avoid long exclusive locks etc. but how do we check the same. i mean for dmls there is a explain/ auto_explain. but for DDLs, how do we check the same. i tried to isolate my setup and use pg_stat_user_tables and monitor the same, which helped, but it is not useful as it does not link me to what process/command invoked the seq scan. am i clear in my question ? if yes, how do i log an alter table that may or may not do a seq scan, that may or may not rewrite the table file on disk etc. its a useless question, i am just playing with it for building knowledge, no requirement as such. /* postgres=# \d t Table "public.t" Column | Type | Collation | Nullable | Default --------+---------+-----------+----------+--------- col1 | integer | | | postgres=# insert into t select 0 from generate_series(1, 1000000) x; INSERT 0 1000000 -- this does a full seq scan as new constraint postgres=# alter table t add constraint col1c check ( col1 < 2 ); ALTER TABLE -- this will not since the table has valid constraint to make it think only worry about changed data ? postgres=# insert into t values (3); ERROR: new row for relation "t" violates check constraint "col1c" DETAIL: Failing row contains (3). -- the below setup making use of not valid and validate constraint still runs a seq scan but does not block writes postgres=# alter table t add constraint col1c_not_neg check ( col1 > -1 ) not valid; ALTER TABLE postgres=# select relname,seq_scan,last_seq_scan, age(last_seq_scan, current_timestamp), seq_tup_read from pg_stat_user_tables where relname = 't'; -[ RECORD 1 ]-+------------------------------ relname | t seq_scan | 7 last_seq_scan | 2024-10-15 19:34:46.837628+00 age | -00:06:46.030264 seq_tup_read | 4000000 postgres=# alter table t validate constraint col1c_not_neg; ALTER TABLE postgres=# select relname,seq_scan,last_seq_scan, age(last_seq_scan, current_timestamp), seq_tup_read from pg_stat_user_tables where relname = 't'; -[ RECORD 1 ]-+------------------------------ relname | t seq_scan | 8 last_seq_scan | 2024-10-15 19:41:50.931282+00 age | -00:00:01.85388 seq_tup_read | 5000000 postgres=# -- now i dont want this seq scan, so i update the pg_constraint (ok we dont do this but i want to trace seq scans) postgres=# alter table t drop constraint col1c_not_neg; ALTER TABLE postgres=# select relname,seq_scan,last_seq_scan, age(last_seq_scan, current_timestamp), seq_tup_read from pg_stat_user_tables where relname = 't'; -[ RECORD 1 ]-+------------------------------ relname | t seq_scan | 8 last_seq_scan | 2024-10-15 19:41:50.931282+00 age | -00:00:21.980611 seq_tup_read | 5000000 postgres=# alter table t add constraint col1c_not_neg check ( col1 > -1 ) not valid; ALTER TABLE postgres=# select oid from pg_constraint where conrelid = 't'::regclass::oid and convalidated = 'f'; -[ RECORD 1 ] oid | 16410 -- i save a seq scan in validate constraint because i know my data. (like in attaching partitions etc) by updating the catalog directly postgres=# update pg_constraint set convalidated = 't' where conrelid = 't'::regclass::oid and convalidated = 'f' and oid = 16410; UPDATE 1 postgres=# select relname,seq_scan,last_seq_scan, age(last_seq_scan, current_timestamp), seq_tup_read from pg_stat_user_tables where relname = 't'; -[ RECORD 1 ]-+------------------------------ relname | t seq_scan | 8 last_seq_scan | 2024-10-15 19:41:50.931282+00 age | -00:05:14.066944 seq_tup_read | 5000000 but how do i log this seq scan here for this sql. */ if this does not make sense, pls ignore. not critical. -- Thanks, Vijay Open to work Resume - Vijaykumar Jain --00000000000029fc4a0624894661 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Hi,

tl;dr
I am trying to le= arn what sql can result in a full seq scan.

Ba= sically there is a lot of info on the internet of what ddl change may take = an access exclusive lock while running=C2=A0a seq scan and hold for long.
=C2=A0And for some cases we can make use of=C2=A0
"= not valid" constraint and then run a validate constraint as work aroun= ds to avoid long exclusive locks etc.
but how do we check the sam= e. i mean for dmls there is a explain/ auto_explain.

but for DDLs, how do we check the same.
i tried to isolate my = setup and use pg_stat_user_tables and monitor the same, which helped, but i= t is not useful as it does not link me to what process/command invoked the = seq scan.

am i clear in my question ?
if yes,=C2=A0
how do i log an alter table that may o= r may not do a seq scan, that may or may not rewrite the table file on disk= etc.
=C2=A0=C2=A0
its a useless question, i am just pl= aying with it for building knowledge, no requirement as such.

/*
postgres=3D# \d t
=C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0Table "public.t= "
=C2=A0Column |=C2=A0 Type=C2=A0 =C2=A0| Collation | Nullab= le | Default
--------+---------+-----------+----------+---------<= /div>
=C2=A0col1=C2=A0 =C2=A0| integer |=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0|=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 |

po= stgres=3D# insert into t select 0 from generate_series(1, 1000000) x;
=
INSERT 0 1000000

-- this does a full seq scan= as new constraint=C2=A0
postgres=3D# alter table t add constrain= t col1c check ( col1 < 2 );
ALTER TABLE
-- this will= not since the table has valid constraint to make it think only worry about= changed data ?
postgres=3D# insert into t values (3);
= ERROR:=C2=A0 new row for relation "t" violates check constraint &= quot;col1c"
DETAIL:=C2=A0 Failing row contains (3).

-- the below setup making use of not valid and validate co= nstraint still runs a seq scan but does not block writes
postgres= =3D# alter table t add constraint col1c_not_neg check ( col1 > -1 ) not = valid;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ALTE= R TABLE
postgres=3D#=C2=A0 select relname,seq_scan,last_= seq_scan, age(last_seq_scan, current_timestamp), seq_tup_read from pg_stat_= user_tables where relname =3D 't';
-[ RECORD 1 ]-+-------= -----------------------
relname=C2=A0 =C2=A0 =C2=A0 =C2=A0| t
seq_scan=C2=A0 =C2=A0 =C2=A0 | 7
last_seq_scan | 2024-10-1= 5 19:34:46.837628+00
age=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= | -00:06:46.030264
seq_tup_read=C2=A0 | 4000000

postgres=3D# alter table t validate constraint col1c_not_neg;
=
ALTER TABLE
postgres=3D#=C2=A0 select relname,seq_scan,last_= seq_scan, age(last_seq_scan, current_timestamp), seq_tup_read from pg_stat_= user_tables where relname =3D 't';
-[ RECORD 1 ]-+-------= -----------------------
relname=C2=A0 =C2=A0 =C2=A0 =C2=A0| t
seq_scan=C2=A0 =C2=A0 =C2=A0 | 8
last_seq_scan | 2024-10-1= 5 19:41:50.931282+00
age=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= | -00:00:01.85388
seq_tup_read=C2=A0 | 5000000

postgres=3D# -- now i dont want this seq scan, so i update the pg_co= nstraint (ok we dont=C2=A0do this but i want to trace seq scans)
=
postgres=3D# alter table t drop constraint col1c_not_neg;
ALTER TABLE
postgres=3D#=C2=A0 select relname,seq_scan,la= st_seq_scan, age(last_seq_scan, current_timestamp), seq_tup_read from pg_st= at_user_tables where relname =3D 't';
-[ RECORD 1 ]-+----= --------------------------
relname=C2=A0 =C2=A0 =C2=A0 =C2=A0| t<= /div>
seq_scan=C2=A0 =C2=A0 =C2=A0 | 8
last_seq_scan | 2024-1= 0-15 19:41:50.931282+00
age=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0| -00:00:21.980611
seq_tup_read=C2=A0 | 5000000

=
postgres=3D# alter table t add constraint col1c_not_neg check ( = col1 > -1 ) not valid;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 ALTER TABLE
postgres=3D# select oid from pg_con= straint where conrelid =3D 't'::regclass::oid and convalidated =3D = 'f';=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 -[ RECORD 1 ]
oid | 16410

-- i save a seq scan in validate constraint because i know my data. = (like in attaching partitions etc) by updating the catalog directly

postgres=3D# update pg_constraint set convalidated =3D &#= 39;t' where conrelid =3D 't'::regclass::oid and convalidated = =3D 'f' and oid =3D 16410;
UPDATE 1
<= br>
postgres=3D#=C2=A0 select relname,seq_scan,last_seq_scan= , age(last_seq_scan, current_timestamp), seq_tup_read from pg_stat_user_tab= les where relname =3D 't';
-[ RECORD 1 ]-+---------------= ---------------
relname=C2=A0 =C2=A0 =C2=A0 =C2=A0| t
s= eq_scan=C2=A0 =C2=A0 =C2=A0 | 8
last_seq_scan | 2024-10-15 19:41:= 50.931282+00
age=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0| -00:05= :14.066944
seq_tup_read=C2=A0 | 5000000

but how do i log this seq scan here for this sql.
*/
<= div>
if this does not make sense,=C2=A0 pls ignore. not criti= cal.
--
Thanks,
Vijay

Open to work
Resume -=C2=A0Vijaykumar Jain
--00000000000029fc4a0624894661--