空間インデックス

(8.0.29)

https://dev.mysql.com/doc/refman/8.0/ja/creating-spatial-indexes.html
https://dev.mysql.com/doc/refman/8.0/ja/spatial-function-reference.html

drop table tab1;
create table tab1 (
 col1 int primary key,
 col2 varchar(255),
 col3 geometry not null SRID 4326
);

※空間インデックスのカラムはnot nullが必要


drop procedure proc1;

delimiter //
create procedure proc1(in x bigint)
begin
  declare wk1 varchar(100);
  declare wk2 varchar(100);

  declare i bigint;
  set i = 0;
  start transaction;
  while i < x do
    set i = i + 1;
    set wk1 = cast( round(rand()*180,2 ) as char) ;
    set wk2 = cast( round(rand()*90,2 ) as char) ;
    -- point(緯度 経度)
    set @g = concat('point(',wk2,' ',wk1,')');
    
    insert into tab1(col1,col2,col3) select i,concat('POINT',i), st_geomfromtext(@g,4326) ;
  end while;
  commit;
end
//
delimiter ;

call proc1(100000);


select count(*) from tab1;
select col1,col2,st_astext(col3) from tab1 limit 10;

analyze table tab1;

CREATE SPATIAL INDEX ind1 ON tab1(col3);

explain analyze
select col1,col2,st_astext(col3)
from tab1
WHERE MBRWithin(col3, st_geomfromtext('LineString(10.00 100.00, 11.00 101.00)', 4326) ) 
;


explain analyze
select  /*+ INDEX(tab1 ind1) */ col1,col2,st_astext(col3)
from tab1
WHERE MBRWithin(col3, st_geomfromtext('LineString(10.00 100.00, 11.00 101.00)', 4326) ) 
;

 

(19c)

https://docs.oracle.com/cd/F19136_01/spatl/sql-indexing-spatial-data.html#GUID-BB6D7C9E-277B-4F49-BDD4-539CFE88D12C
https://docs.oracle.com/cd/F19136_01/spatl/complex-spatial-queries.html#GUID-66516CA7-D36C-4A73-90FC-28C650DDDF68
https://qiita.com/ryotayamanaka/items/6f9954e63dac03fd44d0

 

-- 1. Oracle Spatialインストール
-- インストール対象のPDBはオープンが必要

$ORACLE_HOME/perl/bin/perl $ORACLE_HOME/rdbms/admin/catcon.pl -n 1 -l /home/oracle -v  -b mdinst -c  'PDB$SEED CDB$ROOT PDB1'   -U "SYS"/"oracle" $ORACLE_HOME/md/admin/mdinst.sql

 

-- インストール後確認

connect / as sysdba
set serveroutput on

execute validate_sdo;

select comp_id, control, schema, version, status, comp_name from dba_registry 
where comp_id='SDO';

select object_name, object_type, status from dba_objects
where owner='MDSYS' and status <> 'VALID'
order by object_name;


-- 2. 動作確認

conn test/test@pdb1

drop table tab1 purge;
create table tab1 (
    col1 int primary key,
    col2 varchar2(255),
    col3 sdo_geometry
);

declare
wk1 number;
wk2 number;
begin
for i in 1..100000 loop
  wk1 := round(dbms_random.value()*180,2);
  wk2 := round(dbms_random.value()*90,2);
  
  -- point(経度 緯度)
  insert into tab1(col1,col2,col3) values( i,'POINT'||i, sdo_geometry(2001, 4326, sdo_point_type(wk1, wk2, null), null, null) );

end loop;
end;
/

commit;

select count(*) from tab1;
select * from tab1 fetch first 10 rows only;

exec dbms_stats.gather_table_stats(user, 'TAB1');


※空間索引を作成するには、USER_SDO_GEOM_METADATAにデータ登録が必要。登録していない場合、下記のようなエラーとなる
ORA-29855: ODCIINDEXCREATEルーチンの実行でエラーが発生しました。 ORA-13203:
USER_SDO_GEOM_METADATAビューの読取りに失敗しました。 ORA-13203:
USER_SDO_GEOM_METADATAビューの読取りに失敗しました。 ORA-06512:
"MDSYS.SDO_INDEX_METHOD_10I", 行10

select * from USER_SDO_GEOM_METADATA;

INSERT INTO user_sdo_geom_metadata VALUES (
  'tab1',
  'col3',
  SDO_DIM_ARRAY(
    SDO_DIM_ELEMENT('longitude', -180.0, 180.0, 0.05),
    SDO_DIM_ELEMENT('latitude', -90.0, 90.0, 0.05)
  ),
  4326
);
COMMIT;

 

create index ind1 on tab1(col3)
indextype is mdsys.spatial_index_V2;

 

explain plan for
select col1,col2,col3,sdo_nn_distance(1) distance_in_km
from tab1
where sdo_nn(col3,
      sdo_geometry(2001, 4326, sdo_point_type(15.0, 12.1, null), null, null) ,
     'sdo_num_res=5 distance=1000 unit=km', 1) = 'TRUE'
order by distance_in_km;

select * from table(dbms_xplan.display(format => 'ALL') );

 

 

(14)

https://aginfo.cgk.affrc.go.jp/docs/pgisman/1.3.6/ch04.html#idp66618824
https://qiita.com/takahi/items/37c0a096d2073646ba62

 


OS: CentOS 8

-- 1. PostGISインストール
-- 1.1 必要パッケージのインストール

su - postgres

sudo dnf install libxml2-devel sqlite-devel libtiff-devel libcurl-devel


-- 1.2 geosのインストール
cd
wget http://download.osgeo.org/geos/geos-3.9.2.tar.bz2
tar xvjf geos-3.9.2.tar.bz2
cd geos-3.9.2
./configure
make
sudo make install


-- 1.3 projのインストール

cd
wget https://download.osgeo.org/proj/proj-8.2.0.tar.gz
tar xvzf proj-8.2.0.tar.gz
cd proj-8.2.0
./configure
make
sudo make install


-- 1.4 PostGISのインストール

cd
wget http://download.osgeo.org/postgis/source/postgis-3.1.4.tar.gz
tar xvfz postgis-3.1.4.tar.gz
cd postgis-3.1.4

PG_CONFIG=/usr/pgsql-14/bin/pg_config ./configure --without-protobuf --without-raster
make PG_CONFIG=/usr/pgsql-14/bin/pg_config 
sudo make PG_CONFIG=/usr/pgsql-14/bin/pg_config install


-- 1.5 ライブラリパス設定
sudo vi /etc/ld.so.conf.d/geos.conf
/usr/local/lib

sudo /sbin/ldconfig


-- 1.6 拡張インストール
psql test

SELECT name, default_version,installed_version
FROM pg_available_extensions 
WHERE name LIKE 'postgis%'
;

CREATE EXTENSION postgis;
CREATE EXTENSION postgis_topology;

\dx

 

-- 2. 動作確認


drop table tab1;
create table tab1 (
 col1 int primary key,
 col2 varchar(255),
 col3 geometry(point, 4326)
);


do $$
declare
i bigint;
wk1 varchar(100);
wk2 varchar(100);
wk3 varchar(100);

begin
  i := 1;
  while i <= 100000 loop
    wk1 := round( (random()*180)::numeric ,2)::varchar;
    wk2 := round( (random()*90)::numeric ,2)::varchar;
    -- point(経度 緯度)
    wk3 := 'point('||wk1||' '||wk2||')';
      
    insert into tab1 values (i, 'Point'||i, st_geomfromtext(wk3,4326) );
    i := i+1;
  end loop;
end;
$$;

select count(*) from tab1;
select col1,col2,st_astext(col3) from tab1 limit 10;

analyze tab1;


create index ind1 on tab1 using gist ( col3 );


explain analyze
select col1,col2,st_astext(col3)
from tab1
where st_contains( st_buffer( st_setsrid( st_point( 15.0, 12.1 ) , 4326 ), 1) ,col3)
;

 

(2019)

https://learn.microsoft.com/ja-jp/sql/relational-databases/spatial/create-modify-and-drop-spatial-indexes?view=sql-server-ver15
https://learn.microsoft.com/ja-jp/sql/t-sql/spatial-geometry/ogc-methods-on-geometry-instances?view=sql-server-ver15

 

drop table tab1;
create table tab1 (
 col1 int primary key,
 col2 varchar(255),
 col3 geometry
);

 

begin
set nocount on;
declare @i bigint;
declare @wk1 varchar(100);
declare @wk2 varchar(100);
declare @wk3 varchar(100);

set @i = 1;
begin transaction;
while (@i <= 100000)
  begin
    set @wk1 = cast( round( rand() * 180,2) as varchar);
    set @wk2 = cast( round( rand() * 90,2) as varchar);
    -- point(経度 緯度)
    set @wk3 = 'POINT(' + @wk1 + ' ' + @wk2 + ')';
    insert into tab1 values(@i,'POINT'+cast(@i as varchar), geometry::STGeomFromText(@wk3, 4326) );
    set @i = @i + 1;
  end
end
commit;
go


select count(*) from tab1;
select top(10) col1,col2,col3.STAsText() from tab1;

update statistics tab1;

 

create spatial index ind1 on tab1(col3)
WITH ( BOUNDING_BOX = ( 0, 0, 180, 90 ) );


select col1,col2,col3.STAsText()
from tab1
where col3.STWithin( geometry::STGeomFromText('LineString(80.00 50.00, 150.00 70.00)', 4326) ) = 1
;

 

count文の実行計画

 

MySQLOracleSQL Server ->インデックスがあればフルスキャンされる
PostgreSQL -> 常にテーブルのフルスキャン

(8.0.29)

drop table tab1 ;
create table tab1(col1 int not null,col2 int, col3 int);


drop procedure proc1;

delimiter //
create procedure proc1(in x bigint)
begin
  declare i bigint;
  set i = 0;
  start transaction;
  while i < x do
    set i = i + 1;
    insert into tab1(col1,col2,col3) select ceil(rand()*100000),ceil(rand()*100000),ceil(rand()*100000);
  end while;
  commit;
end
//
delimiter ;

call proc1(10000);


select count(*) from tab1;
select * from tab1 limit 10;

create  index ind11 on tab1(col1);
create  index ind12 on tab1(col2);

analyze table tab1;

 

explain  select count(*) from tab1;
→ index ind11

explain  select count(1) from tab1;
→ index ind11

explain  select count(col1) from tab1;
→ index ind11

explain  select count(col2) from tab1;
→ index ind12

explain  select count(col3) from tab1;
→ ALL

インデックスがあれば使用される

 

(19c)

drop table tab1 purge;
create table tab1(col1 int not null,col2 int,col3 int);

declare
begin
for i in 1..10000 loop
  insert into tab1(col1,col2,col3) values(
      ceil(dbms_random.value()*100000)
    , ceil(dbms_random.value()*100000)
    , ceil(dbms_random.value()*100000)
    );
end loop;
end;
/

commit;


select count(*) from tab1;
select * from tab1 fetch first 10 rows only;

create index ind11 on tab1(col1);
create index ind12 on tab1(col2);

exec dbms_stats.gather_table_stats(user, 'TAB1');


explain plan for select count(*) from tab1;
select * from table(dbms_xplan.display(format => 'ALL') );
→ INDEX FAST FULL SCAN  IND11

explain plan for select count(1) from tab1;
select * from table(dbms_xplan.display(format => 'ALL') );
→ INDEX FAST FULL SCAN  IND11

explain plan for select count(col1) from tab1;
select * from table(dbms_xplan.display(format => 'ALL') );
→ INDEX FAST FULL SCAN  IND11

explain plan for select count(col2) from tab1;
select * from table(dbms_xplan.display(format => 'ALL') );
→ INDEX FAST FULL SCAN  IND12

explain plan for select count(col3) from tab1;
select * from table(dbms_xplan.display(format => 'ALL') );
→ TABLE ACCESS FULL


インデックスがあれば使用される

 

(14)

drop table tab1 ;
create table tab1(col1 int not null ,col2 int, col3 int);

insert into tab1(col1,col2,col3) select 
     ceil(random()*100000)
   , ceil(random()*100000)
   , ceil(random()*100000)
   from generate_series(1,10000) g;

 

select count(*) from tab1;
select * from tab1 limit 10;

create index ind11 on tab1(col1);
create index ind12 on tab1(col2);

analyze tab1;

explain analyze select count(*) from tab1;
→ Seq Scan on tab1

explain analyze select count(1) from tab1;
→ Seq Scan on tab1

explain analyze select count(col1) from tab1;
→ Seq Scan on tab1

explain analyze select count(col2) from tab1;
→ Seq Scan on tab1

explain analyze select count(col3) from tab1;
→ Seq Scan on tab1


インデックスは使用されない。可視性チェックが必要のためと思われる。

 

(2019)


drop table tab1 ;
create table tab1(col1 int not null ,col2 int ,col3 int);


set nocount on
declare @i bigint;
set @i = 1;
begin transaction;
while @i <= 10000
begin
  insert into tab1(col1,col2,col3) select ceiling(rand()*100000),ceiling(rand()*100000),ceiling(rand()*100000);
  set @i = @i + 1;
end
commit;

 


select count(*) from tab1;
select top(10) * from tab1 ;

create index ind11 on tab1(col1);
create index ind12 on tab1(col2);

update statistics tab1;

set showplan_all on
go

select count(*) from tab1;
→ Index Scan ind12

select count(1) from tab1;
→ Index Scan ind12

select count(col1) from tab1;
→ Index Scan ind12

select count(col2) from tab1;
→ Index Scan ind12

select count(col3) from tab1;
→ Table Scan


インデックスがあれば使用される
見積コストに相違はないが、ind12が使用される。

 

セミジョイン/アンチジョイン

 

作業概要:
「in」「exists」「not in」「not exists」それぞれについて
結合キーカラムが nullable の場合とnot nullの場合の実行計画を確認した

結果:
「in」「exists」「not exists」については、結合キーカラムのnull属性に関係なくサブクエリのテーブルでインデックスが使用された。


「not in」については、結合キーカラムのnull属性に依存して実行計画が変化した。

結合キーカラムが nullable の場合、サブクエリのテーブルでフルスキャンとなった。(MySQLOraclePostgreSQLSQL Server)
結合キーカラムが not null の場合、サブクエリのテーブルでインデックスが使用された。(MySQLOracleSQL Server)
結合キーカラムが not null の場合、サブクエリのテーブルでフルスキャンのままだった。(PostgreSQL)

 

(8.0.29)

drop table tab1 ;
drop table tab2 ;
create table tab1(col1 int   ,col2 int);
create table tab2(col1 int   ,col2 int);


drop procedure proc1;

delimiter //
create procedure proc1(in x bigint)
begin
  declare i bigint;
  set i = 0;
  start transaction;
  while i < x do
    set i = i + 1;
    insert into tab1(col1,col2) select i, ceil(rand()*100000);
    insert into tab2(col1,col2) select i, ceil(rand()*100000);
  end while;
  commit;
end
//
delimiter ;

call proc1(10000);


select count(*) from tab1;
select count(*) from tab2;
select * from tab1 limit 10;
select * from tab2 limit 10;

create  index ind1 on tab1(col1);
create  index ind2 on tab2(col1);

analyze table tab1;
analyze table tab2;

explain analyze
select count(*)
from tab1 t1
where t1.col1  in ( select col1 from tab2 where col2 < 100 )
and t1.col2 < 10;

→ Nested loop semijoin/Table scan on t1/Index lookup on tab2 using ind2

explain analyze
select count(*)
from tab1 t1
where exists ( select 1 from tab2 where col2 < 100 and col1 = t1.col1 )
and t1.col2 < 10;

→ Nested loop semijoin/Table scan on t1/Index lookup on tab2 using ind2


explain analyze
select count(*)
from tab1 t1
where t1.col1 not in ( select col1 from tab2 where col2 < 100 )
and t1.col2 < 10;

→ Filter/Table scan on t1/Table scan on tab2 ★

※結合キーのカラム(col1)がnot nullの場合、他と同様にインデックスが使用される
→ Nested loop antijoin/Table scan on t1/Index lookup on tab2 using ind2


explain analyze
select count(*)
from tab1 t1
where not exists ( select 1 from tab2 where col2 < 100 and col1 = t1.col1 )
and t1.col2 < 10;

→ Nested loop antijoin/Table scan on t1/Index lookup on tab2 using ind2

 

(19c)

 

drop table tab1 purge;
drop table tab2 purge;
create table tab1(col1 int    ,col2 int);
create table tab2(col1 int    ,col2 int);

declare
begin
for i in 1..10000 loop
  insert into tab1(col1,col2) values(i, ceil(dbms_random.value()*100000) );
  insert into tab2(col1,col2) values(i, ceil(dbms_random.value()*100000) );
  
end loop;
end;
/

commit;

 

select count(*) from tab1;
select count(*) from tab2;
select * from tab1 fetch first 10 rows only;
select * from tab2 fetch first 10 rows only;

create index ind1 on tab1(col1);
create index ind2 on tab2(col1);

exec dbms_stats.gather_table_stats(user, 'TAB1');
exec dbms_stats.gather_table_stats(user, 'TAB2');


explain plan for
select count(*)
from tab1 t1
where t1.col1  in ( select col1 from tab2 where col2 < 100 )
and t1.col2 < 10;
select * from table(dbms_xplan.display(format => 'ALL') );

→ NESTED LOOPS SEMI/TABLE ACCESS FULL/INDEX RANGE SCAN


explain plan for
select count(*)
from tab1 t1
where exists ( select 1 from tab2 where col2 < 100 and col1 = t1.col1 )
and t1.col2 < 10;
select * from table(dbms_xplan.display(format => 'ALL') );

→ NESTED LOOPS SEMI/TABLE ACCESS FULL/INDEX RANGE SCAN

 

explain plan for
select count(*)
from tab1 t1
where t1.col1 not in ( select col1 from tab2 where col2 < 100 )
and t1.col2 < 10;
select * from table(dbms_xplan.display(format => 'ALL') );

→ HASH JOIN ANTI NA/TABLE ACCESS FULL/TABLE ACCESS FULL ★


※結合キーのカラム(col1)がnot nullの場合、他と同様にインデックスが使用される
→ NESTED LOOPS SEMI/TABLE ACCESS FULL/INDEX RANGE SCAN


explain plan for
select count(*)
from tab1 t1
where not exists ( select 1 from tab2 where col2 < 100 and col1 = t1.col1 )
and t1.col2 < 10;
select * from table(dbms_xplan.display(format => 'ALL') );

→ NESTED LOOPS ANTI/TABLE ACCESS FULL/INDEX RANGE SCAN

 

(14)


drop table tab1 ;
drop table tab2 ;
create table tab1(col1 int  ,col2 int);
create table tab2(col1 int  ,col2 int);

insert into tab1(col1,col2) select g, ceil(random()*100000) from generate_series(1,10000) g;
insert into tab2(col1,col2) select g, ceil(random()*100000) from generate_series(1,10000) g;

 

select count(*) from tab1;
select count(*) from tab2;
select * from tab1 limit 10;
select * from tab2 limit 10;

create index ind1 on tab1(col1);
create index ind2 on tab2(col1);

analyze tab1;
analyze tab2;


explain analyze
select count(*)
from tab1 t1
where t1.col1  in ( select col1 from tab2 where col2 < 100 )
and t1.col2 < 10;

→ Nested loop semijoin/Seq Scan on tab1 t1/Index Scan using ind2 on tab2

explain analyze
select count(*)
from tab1 t1
where exists ( select 1 from tab2 where col2 < 100 and col1 = t1.col1 )
and t1.col2 < 10;

→ Nested loop semijoin/Seq Scan on tab1 t1/Index Scan using ind2 on tab2


explain analyze
select count(*)
from tab1 t1
where t1.col1 not in ( select col1 from tab2 where col2 < 100 )
and t1.col2 < 10;

→ Seq Scan on tab1 t1/SubPlan 1/Seq Scan on tab2 ★


※結合キーのカラム(col1)がnot nullの場合でもインデックスは使用されない ★★


explain analyze
select count(*)
from tab1 t1
where not exists ( select 1 from tab2 where col2 < 100 and col1 = t1.col1 )
and t1.col2 < 10;

→ Nested Loop Anti Join/Seq Scan on tab1 t1/Index Scan using ind2 on tab2

 

(2019)

drop table tab1 ;
drop table tab2 ;
create table tab1(col1 int  ,col2 int);
create table tab2(col1 int  ,col2 int);


set nocount on
declare @i bigint;
set @i = 1;
begin transaction;
while @i <= 10000
begin
  insert into tab1(col1,col2) select @i, ceiling(rand()*100000);
  insert into tab2(col1,col2) select @i, ceiling(rand()*100000);
  set @i = @i + 1;
end
commit;

 


select count(*) from tab1;
select count(*) from tab2;
select top(10) * from tab1 ;
select top(10) * from tab2 ;

create index ind1 on tab1(col1);
create index ind2 on tab2(col1);

update statistics tab1;
update statistics tab2;

set showplan_all on
go

select count(*)
from tab1 t1
where t1.col1  in ( select col1 from tab2 where col2 < 100 )
and t1.col2 < 10;

→ Nested Loops(Left Semi Join)/Table Scan/Index Seek

 


select count(*)
from tab1 t1
where exists ( select 1 from tab2 where col2 < 100 and col1 = t1.col1 )
and t1.col2 < 10;

→ Nested Loops(Left Semi Join)/Table Scan/Index Seek


select count(*)
from tab1 t1
where t1.col1 not in ( select col1 from tab2 where col2 < 100 )
and t1.col2 < 10;

→ Nested Loops(Left Anti Join)/Table Scan/Table Scan  ★


※結合キーのカラム(col1)がnot nullの場合、他と同様にインデックスが使用される
→ Nested Loops(Left Anti Join)/Table Scan/Index Seek


select count(*)
from tab1 t1
where not exists ( select 1 from tab2 where col2 < 100 and col1 = t1.col1 )
and t1.col2 < 10;

→ Nested Loops(Left Anti Join)/Table Scan/Index Seek

 

ヒント句を複数指定した場合の挙動

MySQL,Oracle,PostgreSQLともに最初に指定したヒント句が有効

 

(8.0.29)

パーサーは、SELECT, UPDATE, INSERT, REPLACE ステートメントおよび DELETE ステートメントの最初のキーワードの後にオプティマイザヒントコメントを認識します。


drop table tab1 ;
drop table tab2 ;
create table tab1(col1 int,col2 int);
create table tab2(col1 int,col2 int);


drop procedure proc1;

delimiter //
create procedure proc1(in x bigint)
begin
  declare i bigint;
  set i = 0;
  start transaction;
  while i < x do
    set i = i + 1;
    insert into tab1(col1,col2) select ceil(rand()*100000), ceil(rand()*100000);
    insert into tab2(col1,col2) select ceil(rand()*100000), ceil(rand()*100000);
  end while;
  commit;
end
//
delimiter ;

call proc1(10000);


select count(*) from tab1;
select count(*) from tab2;
select * from tab1 limit 10;
select * from tab2 limit 10;

create index ind1 on tab1(col2);
create index ind2 on tab2(col2);


explain analyze
select /*+ JOIN_ORDER(t2,t1)  */ /*+ NO_INDEX(t1 ind1) */ count(*)
from tab1 t1 inner join tab2 t2
on t1.col1 = t2.col1
and t1.col2 < 1000;
show warnings;

explain analyze
select /*+ NO_INDEX(t1 ind1) */ /*+ JOIN_ORDER(t2,t1)  */ count(*)
from tab1 t1 inner join tab2 t2
on t1.col1 = t2.col1
and t1.col2 < 1000;
show warnings;


→ マニュアル記載どおり、最初に指定したヒント句が有効

(19c)

ヒント構文は、文ブロックを開始するINSERT、UPDATE、DELETE、SELECTまたはMERGEのいずれかのキーワードの直後でのみ指定できます。

drop table tab1 purge;
drop table tab2 purge;
create table tab1(col1 int,col2 int);
create table tab2(col1 int,col2 int);

declare
begin
for i in 1..10000 loop
  insert into tab1(col1,col2) values(ceil(dbms_random.value()*100000), ceil(dbms_random.value()*100000) );
  insert into tab2(col1,col2) values(ceil(dbms_random.value()*100000), ceil(dbms_random.value()*100000) );
  
end loop;
end;
/

commit;

 

select count(*) from tab1;
select count(*) from tab2;
select * from tab1 fetch first 10 rows only;
select * from tab2 fetch first 10 rows only;

create index ind1 on tab1(col2);
create index ind2 on tab2(col2);


explain plan for
select /*+ LEADING(t2 t1) */ /*+ INDEX(t1 ind1) */  count(*)
from tab1 t1 inner join tab2 t2
on t1.col1 = t2.col1
and t1.col2 < 1000;
select * from table(dbms_xplan.display(format => 'ALL') );

explain plan for
select /*+ INDEX(t1 ind1) */  /*+ LEADING(t2 t1) */  count(*)
from tab1 t1 inner join tab2 t2
on t1.col1 = t2.col1
and t1.col2 < 1000;
select * from table(dbms_xplan.display(format => 'ALL') );


→ マニュアル記載どおり、最初に指定したヒント句が有効

(14)

指定したいヒントを、実行計画を制御したいクエリの先頭のSQLブロックコメントの中に記述します。

※途中にもヒント句を記載できる模様であるが、いろいろ制約があるため、実装は非現実的


drop table tab1 ;
drop table tab2 ;
create table tab1(col1 int,col2 int);
create table tab2(col1 int,col2 int);

insert into tab1(col1,col2) select ceil(random()*100000), ceil(random()*100000) from generate_series(1,10000);
insert into tab2(col1,col2) select ceil(random()*100000), ceil(random()*100000) from generate_series(1,10000);

 

select count(*) from tab1;
select count(*) from tab2;
select * from tab1 limit 10;
select * from tab2 limit 10;

create index ind1 on tab1(col2);
create index ind2 on tab2(col2);


set pg_hint_plan.debug_print = 'on';
show pg_hint_plan.debug_print;

 

/*+ MergeJoin(t1 t2)   */
/*+ IndexScan(t1 ind1) */
explain analyze
select count(*)
from tab1 t1 inner join tab2 t2
on t1.col1 = t2.col1
and t1.col2 < 1000;

/*+ IndexScan(t1 ind1) */
/*+ MergeJoin(t1 t2)   */
explain analyze
select count(*)
from tab1 t1 inner join tab2 t2
on t1.col1 = t2.col1
and t1.col2 < 1000;

→ マニュアル記載どおり、最初に指定したヒント句が有効

 

(2019)


SQL構文の一部であるため、OPTION を複数指定すると構文エラーとなる

 

{IAM}ウェブ ID フェデレーション

https://qiita.com/hyj624117615/items/ca4a8bc8c269098aaeef

作業端末: macOS 12.4


-- 1. 準備作業【AWS

curl "https://awscli.amazonaws.com/AWSCLIV2.pkg" -o "AWSCLIV2.pkg"
sudo installer -pkg AWSCLIV2.pkg -target /
which aws
aws --version

 


-- 2. 準備作業【GCP

curl https://dl.google.com/dl/cloudsdk/channels/rapid/downloads/google-cloud-cli-401.0.0-darwin-x86_64.tar.gz -o google-cloud-cli-401.0.0-darwin-x86_64.tar.gz
tar xvzf google-cloud-cli-401.0.0-darwin-x86_64.tar.gz
./google-cloud-sdk/install.sh
./google-cloud-sdk/bin/gcloud init
gcloud --version


gcloud init

gcloud auth list

 

-- 3. プロジェクト、サービスアカウント、VMインスタンスの作成【GCP

-- 3.1 プロジェクトの作成

gcloud projects list


gcloud projects create project1111111111 \
--name="project1111111111"

gcloud projects describe project1111111111

-- 3.2 プロジェクトを請求先アカウントに紐づける(GUIから実施)

-- 3.3 プロジェクト設定

gcloud config list
gcloud config set project project1111111111
gcloud config list

-- 3.4 Compute Engineの有効化

gcloud services enable compute.googleapis.com

-- 3.5 サービスアカウント作成

gcloud iam service-accounts create sa0001 --display-name="sa0001"
gcloud iam service-accounts list
gcloud iam service-accounts describe sa0001@project1111111111.iam.gserviceaccount.com


-- 3.6 VMインスタンス作成


gcloud compute instances list


gcloud compute instances create instance-1 \
--project=project1111111111 \
--zone=asia-northeast1-a \
--machine-type=e2-micro \
--network-interface=network-tier=PREMIUM,subnet=default \
--maintenance-policy=MIGRATE \
--provisioning-model=STANDARD \
--service-account=sa0001@project1111111111.iam.gserviceaccount.com \
--scopes=https://www.googleapis.com/auth/cloud-platform \
--create-disk=auto-delete=yes,boot=yes,device-name=instance-1,image=projects/centos-cloud/global/images/centos-7-v20220920,mode=rw,size=20,type=projects/project1111111111/zones/asia-northeast1-a/diskTypes/pd-balanced \
--no-shielded-secure-boot \
--shielded-vtpm \
--shielded-integrity-monitoring \
--reservation-affinity=any


-- 3.7 ミドルウェア等をVMインスタンスにインストール
VMインスタンスにログインして実施

gcloud compute ssh --zone "asia-northeast1-a" "instance-1"  --project "project1111111111"

 

sudo yum install -y python3-pip
sudo yum install unzip -y
curl -L -o gcp-to-aws.zip https://github.com/cevoaustralia/gcp-sa-to-aws-iam-role/archive/master.zip
unzip gcp-to-aws.zip
cd gcp-sa-to-aws-iam-role-master/gcp
sudo pip3 install -r requirements.txt

aws --version

cd ~
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install
aws --version

 


-- 4. ロール作成【AWS

-- 4.1 ロールの作成
※"accounts.google.com:aud"にはGCPVMインスタンスに指定したサービスアカウントのuniqueIdを指定する

vim role01.json

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Federated": "accounts.google.com"
            },
            "Action": "sts:AssumeRoleWithWebIdentity",
            "Condition": {
                "StringEquals": {
                    "accounts.google.com:aud": "222222222222222222222"
                }
            }
        }
    ]
}

 

aws iam create-role \
--role-name role01 \
--assume-role-policy-document file://role01.json

-- 4.2 ポリシーをロールにアタッチ

aws iam attach-role-policy \
--policy-arn arn:aws:iam::aws:policy/AmazonS3FullAccess \
--role-name role01

 

 

-- 5. 動作確認【GCP
VMインスタンスにログインして実施

gcloud compute ssh --zone "asia-northeast1-a" "instance-1"  --project "project1111111111"

cd ~/gcp-sa-to-aws-iam-role-master/gcp
ll
cat get_aws_creds.py 


./get_aws_creds.py arn:aws:iam::999999999999:role/role01

 

aws sts get-caller-identity
cat ~/.aws/credentials 

 

export AWS_DEFAULT_REGION=ap-northeast-1

aws s3 ls 
aws s3 mb s3://bucket123
aws s3 ls 
aws s3 rb s3://bucket123 --force
aws s3 ls 


-- 6. クリーンアップ【GCP

-- プロジェクト削除

gcloud projects list

gcloud projects delete project1111111111


-- 7. クリーンアップ【AWS

-- ロールの削除
aws iam list-roles | grep role01

aws iam detach-role-policy \
--role-name role01 \
--policy-arn arn:aws:iam::aws:policy/AmazonS3FullAccess


aws iam delete-role --role-name role01

 

 

{S3}特定の VPC エンドポイントまたは IP アドレスを使用して Amazon S3 バケットへのアクセスを制限する

 

https://dev.classmethod.jp/articles/aws-s3-rest-api-access-vpc/
https://aws.amazon.com/jp/premiumsupport/knowledge-center/block-s3-traffic-vpc-ip/
https://dev.classmethod.jp/articles/vpc-endpoint-gateway-type/


作業概要
EC2インスタンスを2つ作成(インスタンス1、インスタンス2)
ゲートウェイ型S3エンドポイントを作成
インスタンス1、インスタンス2からS3にアクセスできることを確認
インスタンス1のIPアドレスのみ許可するバケットポリシーを作成
インスタンス1はアクセスできるが、インスタンス2からアクセスできないことを確認

 

-- 1. 事前準備

-- 1.1 aws cli version 2 インストール

curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install
aws --version

 

-- 1.2 jqインストール

sudo yum -y install jq


-- 2. S3バケット作成

aws s3 mb s3://bucket123
aws s3 ls


-- 3. EC2インスタンス起動

aws ec2 run-instances \
--image-id ami-0404778e217f54308 \
--instance-type t3.nano \
--key-name key1 \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=instance01}]' \
--instance-market-options '{"MarketType": "spot","SpotOptions": {"SpotInstanceType": "one-time"}}'

aws ec2 run-instances \
--image-id ami-0404778e217f54308 \
--instance-type t3.nano \
--key-name key1 \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=instance02}]' \
--instance-market-options '{"MarketType": "spot","SpotOptions": {"SpotInstanceType": "one-time"}}'

aws ec2 describe-instances


-- 4. S3ゲートウェイエンドポイントの作成

aws ec2 create-vpc-endpoint \
--vpc-endpoint-type Gateway \
--vpc-id vpc-11111111111111111 \
--service-name com.amazonaws.ap-northeast-1.s3 \
--route-table-ids rtb-22222222222222222

aws ec2 describe-vpc-endpoints

 


-- 5. S3アクセス確認(バケットポリシー追加前)
aws s3 ls s3://bucket123 --recursive


-- 6. S3バケットポリシー追加

vim b.json

{
  "Id": "VpcSourceIp",
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "VpcSourceIp",
      "Action": "s3:*",
      "Effect": "Deny",
      "Resource": [
        "arn:aws:s3:::bucket123",
        "arn:aws:s3:::bucket123/*"
      ],
      "Condition": {
        "NotIpAddress": {
          "aws:VpcSourceIp": [
            "172.31.20.56/32"
          ]
        }
      },
      "Principal": "*"
    }
  ]
}

aws s3api put-bucket-policy \
--bucket bucket123 \
--policy file://b.json


aws s3api get-bucket-policy \
--bucket bucket123

インスタンス1以外で実行している場合、エラーになる


-- 7. S3アクセス確認(バケットポリシー追加後)
aws s3 ls s3://bucket123 --recursive

インスタンス1はアクセスできるが、その他のインスタンスからアクセスできない

 

 

-- 8. クリーンアップ


-- バケット削除
aws s3 rb s3://bucket123 --force
aws s3 ls


-- S3ゲートウェイエンドポイントの削除
aws ec2 describe-vpc-endpoints

aws ec2 delete-vpc-endpoints \
--vpc-endpoint-ids vpce-33333333333333333

-- インスタンス削除

aws ec2 describe-instances

aws ec2 terminate-instances \
--instance-ids i-44444444444444444

aws ec2 terminate-instances \
--instance-ids i-55555555555555555

 

 

 

{VPC}VPC ピア接続を操作する(クロスアカウントの場合)

 

https://dev.classmethod.jp/articles/set-route-53-private-zone-across-accounts/
https://dev.classmethod.jp/articles/vpc-peering-different-awsaccount/


前提: 

アカウント: A
VPC: 10.0.0.0/16
サブネット: 10.0.0.0/24
プライベートホストゾーン名: zone20220919.local


アカウント: B
VPC: 10.1.0.0/16
サブネット: 10.1.0.0/24
プライベートホストゾーン名: zone20220919.local

 

-- 1. 事前準備

-- 1.1 aws cli version 2 インストール

curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install
aws --version

 

-- 1.2 jqインストール


sudo yum -y install jq

 

-- 2. VPC、サブネット作成[アカウントA]


-- 2.1 VPC(10.0.0.0/16)を作成する

aws ec2 create-vpc \
--cidr-block 10.0.0.0/16 \
--instance-tenancy default \
--tag-specifications 'ResourceType=vpc,Tags=[{Key=Name,Value=vpc01}]' 


aws ec2 describe-vpcs
aws ec2 describe-vpcs | jq -r '.Vpcs.VpcId'


-- 2.2 サブネット(10.0.0.0/24)を作成する


aws ec2 create-subnet \
--availability-zone ap-northeast-1a \
--cidr-block 10.0.0.0/24 \
--vpc-id vpc-11111111111111111 \
--tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=subnet01}]' 

 

aws ec2 describe-subnets
aws ec2 describe-subnets | jq -r '.Subnets.SubnetId'


-- 2.3 インターネットゲートウェイを作成する


aws ec2 create-internet-gateway \
--tag-specifications 'ResourceType=internet-gateway,Tags=[{Key=Name,Value=igw01}]' 


aws ec2 describe-internet-gateways
aws ec2 describe-internet-gateways | jq -r '.InternetGateways.InternetGatewayId'


-- 2.4 インターネットゲートウェイVPCにアタッチする
aws ec2 attach-internet-gateway \
--internet-gateway-id igw-22222222222222222 \
--vpc-id vpc-11111111111111111


-- 2.5 ルートテーブルのデフォルトゲートウェイとしてインターネットゲートウエイを指定する

aws ec2 describe-route-tables
aws ec2 describe-route-tables | jq -r '.RouteTables.RouteTableId'

aws ec2 create-route \
--destination-cidr-block 0.0.0.0/0 \
--gateway-id igw-22222222222222222 \
--route-table-id rtb-33333333333333333

 


-- 2.6 インスタンス作成(FW設定含む)

aws ec2 run-instances \
--image-id ami-0404778e217f54308 \
--instance-type t3.nano \
--key-name key1 \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=instance01}]' \
--subnet-id subnet-44444444444444444 \
--associate-public-ip-address


0.0.0.0/0からのSSH許可追加

aws ec2 authorize-security-group-ingress \
--group-id sg-55555555555555555 \
--protocol tcp \
--port 22 \
--cidr 0.0.0.0/0 \
--tag-specifications 'ResourceType=security-group-rule,Tags=[{Key=Name,Value=fw01}]' 

 

10.1.0.0/24からのアクセス許可


aws ec2 authorize-security-group-ingress \
--group-id sg-55555555555555555 \
--protocol all \
--port all \
--cidr 10.1.0.0/24 \
--tag-specifications 'ResourceType=security-group-rule,Tags=[{Key=Name,Value=fw02}]' 


-- 2.7 enableDnsHostnames および enableDnsSupport  を true に設定


aws ec2 describe-vpc-attribute \
--attribute enableDnsSupport \
--vpc-id vpc-11111111111111111

aws ec2 describe-vpc-attribute \
--attribute enableDnsHostnames \
--vpc-id vpc-11111111111111111

aws ec2 modify-vpc-attribute \
--enable-dns-hostnames \
--vpc-id vpc-11111111111111111

aws ec2 modify-vpc-attribute \
--enable-dns-support \
--vpc-id vpc-11111111111111111

 

-- 2.8 プライベートホストゾーンの作成

aws route53 create-hosted-zone \
--name zone20220919.local \
--vpc VPCRegion=ap-northeast-1,VPCId=vpc-11111111111111111 \
--caller-reference 2022-09-16-23:09

aws route53 list-hosted-zones


-- 2.9 EC2インスタンスのプライベートIPアドレスをAレコードで登録する


vim a.json

{
  "Comment": "CREATE/DELETE/UPSERT a record ",
  "Changes": [
    { "Action": "UPSERT",
      "ResourceRecordSet": { "Name": "instance01.zone20220919.local.",
                             "Type": "A",
                             "TTL": 300,
                             "ResourceRecords": [
                                 { "Value": "10.0.0.85" }
                             ]
                           }
    }
  ]
}


aws route53 change-resource-record-sets \
--hosted-zone-id 666666666666666666666 \
--change-batch file://a.json

 

aws route53 list-resource-record-sets \
--hosted-zone-id 666666666666666666666

 

 

 


-- 3. VPC、サブネット作成[アカウントB]

-- 3.1 VPC(10.1.0.0/16)を作成する

aws ec2 create-vpc \
--cidr-block 10.1.0.0/16 \
--instance-tenancy default \
--tag-specifications 'ResourceType=vpc,Tags=[{Key=Name,Value=vpc11}]' 


aws ec2 describe-vpcs
aws ec2 describe-vpcs | jq -r '.Vpcs.VpcId'


-- 3.2 サブネット(10.1.0.0/24)を作成する


aws ec2 create-subnet \
--availability-zone ap-northeast-1a \
--cidr-block 10.1.0.0/24 \
--vpc-id vpc-77777777777777777 \
--tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=subnet11}]' 

 

aws ec2 describe-subnets
aws ec2 describe-subnets | jq -r '.Subnets.SubnetId'


-- 3.3 インターネットゲートウェイを作成する


aws ec2 create-internet-gateway \
--tag-specifications 'ResourceType=internet-gateway,Tags=[{Key=Name,Value=igw11}]' 


aws ec2 describe-internet-gateways
aws ec2 describe-internet-gateways | jq -r '.InternetGateways.InternetGatewayId'


-- 3.4 インターネットゲートウェイVPCにアタッチする
aws ec2 attach-internet-gateway \
--internet-gateway-id igw-88888888888888888 \
--vpc-id vpc-77777777777777777


-- 3.5 ルートテーブルのデフォルトゲートウェイとしてインターネットゲートウエイを指定する

aws ec2 describe-route-tables
aws ec2 describe-route-tables | jq -r '.RouteTables.RouteTableId'

aws ec2 create-route \
--destination-cidr-block 0.0.0.0/0 \
--gateway-id igw-88888888888888888 \
--route-table-id rtb-99999999999999999

 


-- 3.6 インスタンス作成(FW設定含む)

aws ec2 run-instances \
--image-id ami-0404778e217f54308 \
--instance-type t3.nano \
--key-name key1 \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=instance11}]' \
--subnet-id subnet-00000000000000000 \
--associate-public-ip-address

 


0.0.0.0/0からのSSH許可追加

aws ec2 authorize-security-group-ingress \
--group-id sg-aaaaaaaaaaaaaaaaa \
--protocol tcp \
--port 22 \
--cidr 0.0.0.0/0 \
--tag-specifications 'ResourceType=security-group-rule,Tags=[{Key=Name,Value=fw11}]' 

 

10.0.0.0/24からのアクセス許可


aws ec2 authorize-security-group-ingress \
--group-id sg-aaaaaaaaaaaaaaaaa \
--protocol all \
--port all \
--cidr 10.0.0.0/24 \
--tag-specifications 'ResourceType=security-group-rule,Tags=[{Key=Name,Value=fw12}]' 

 


-- 3.7 enableDnsHostnames および enableDnsSupport  を true に設定


aws ec2 describe-vpc-attribute \
--attribute enableDnsSupport \
--vpc-id vpc-77777777777777777

aws ec2 describe-vpc-attribute \
--attribute enableDnsHostnames \
--vpc-id vpc-77777777777777777

aws ec2 modify-vpc-attribute \
--enable-dns-hostnames \
--vpc-id vpc-77777777777777777

aws ec2 modify-vpc-attribute \
--enable-dns-support \
--vpc-id vpc-77777777777777777

 


-- 4. VPCピアリング作成

-- 4.1 作成[アカウントA]

aws ec2 create-vpc-peering-connection \
--peer-owner-id bbbbbbbbbbbb \
--peer-vpc-id vpc-77777777777777777 \
--vpc-id vpc-11111111111111111 \
--tag-specifications 'ResourceType=vpc-peering-connection,Tags=[{Key=Name,Value=pcx01}]' 

aws ec2 describe-vpc-peering-connections

 

-- 4.2 承諾[アカウントB]

aws ec2 accept-vpc-peering-connection \
--vpc-peering-connection-id pcx-ccccccccccccccccc

 


-- 5. VPCピアリング間のルート追加

-- 5.1 ルート追加[アカウントA]

aws ec2 create-route \
--destination-cidr-block 10.1.0.0/16 \
--gateway-id pcx-ccccccccccccccccc \
--route-table-id rtb-33333333333333333

-- 5.2 ルート追加[アカウントB]

aws ec2 create-route \
--destination-cidr-block 10.0.0.0/16 \
--gateway-id pcx-ccccccccccccccccc \
--route-table-id rtb-99999999999999999

 


-- 6. pingで疎通確認

AWSVPCピアリング間 vpc01 -> vpc11

ping 10.1.0.170

AWSVPCピアリング間 vpc01 <- vpc11

ping 10.0.0.85

 

-- 7. プライベートホストゾーンのピアリング先アカウントへの紐づけ

-- 7.1 紐づけ許可[アカウントA]

VPCは許可するアカウントBのVPCを指定する


aws route53 create-vpc-association-authorization \
--hosted-zone-id 666666666666666666666 \
--vpc VPCRegion=ap-northeast-1,VPCId=vpc-77777777777777777

aws route53 list-hosted-zones

aws route53 list-vpc-association-authorizations \
--hosted-zone-id 666666666666666666666

aws route53 get-hosted-zone \
--id 666666666666666666666

 

-- 7.2 紐づけ実施[アカウントB]

aws route53 associate-vpc-with-hosted-zone \
--hosted-zone-id 666666666666666666666 \
--vpc VPCRegion=ap-northeast-1,VPCId=vpc-77777777777777777

 

-- 7.3 EC2インスタンスのプライベートIPアドレスをAレコードで登録する[アカウントA]
※紐づけ実施後もアカウントBからはホストゾーンを参照できない

vim a.json

{
  "Comment": "CREATE/DELETE/UPSERT a record ",
  "Changes": [
    { "Action": "UPSERT",
      "ResourceRecordSet": { "Name": "instance11.zone20220919.local.",
                             "Type": "A",
                             "TTL": 300,
                             "ResourceRecords": [
                                 { "Value": "10.1.0.170" }
                             ]
                           }
    }
  ]
}


aws route53 change-resource-record-sets \
--hosted-zone-id 666666666666666666666 \
--change-batch file://a.json

 

aws route53 list-resource-record-sets \
--hosted-zone-id 666666666666666666666

 

 

-- 8. 名前解決確認

各アカウントで下記コマンドを実行し、名前解決できることを確認

nslookup instance01.zone20220919.local

nslookup instance11.zone20220919.local

 


-- 9. VPCピアリング削除[アカウントA]


aws ec2 delete-vpc-peering-connection \
--vpc-peering-connection-id pcx-ccccccccccccccccc

aws ec2 describe-vpc-peering-connections


-- 10. クリーンアップ[アカウントB]


-- インスタンス削除

aws ec2 describe-instances

aws ec2 terminate-instances \
--instance-ids i-ddddddddddddddddd

 

-- インターネットゲートウェイ削除(VPCからデタッチしてから)

aws ec2 describe-internet-gateways
aws ec2 describe-internet-gateways | jq -r '.InternetGateways.InternetGatewayId'

aws ec2 detach-internet-gateway \
--internet-gateway-id igw-88888888888888888 \
--vpc-id vpc-77777777777777777

aws ec2 delete-internet-gateway \
--internet-gateway-id igw-88888888888888888


-- サブネット削除


aws ec2 describe-subnets
aws ec2 describe-subnets | jq -r '.Subnets.SubnetId'

aws ec2  delete-subnet \
--subnet-id subnet-00000000000000000

 

-- VPC削除

aws ec2  delete-vpc \
--vpc-id vpc-77777777777777777

aws ec2 describe-vpcs
aws ec2 describe-vpcs | jq -r '.Vpcs.VpcId'

 

-- 11. クリーンアップ[アカウントA]

 

-- Aレコードの削除


vim a.json

{
  "Comment": "CREATE/DELETE/UPSERT a record ",
  "Changes": [
    { "Action": "DELETE",
      "ResourceRecordSet": { "Name": "instance01.zone20220919.local.",
                             "Type": "A",
                             "TTL": 300,
                             "ResourceRecords": [
                                 { "Value": "10.0.0.85" }
                             ]
                           }
    },
    { "Action": "DELETE",
      "ResourceRecordSet": { "Name": "instance11.zone20220919.local.",
                             "Type": "A",
                             "TTL": 300,
                             "ResourceRecords": [
                                 { "Value": "10.1.0.170" }
                             ]
                           }
    }
  ]
}


aws route53 change-resource-record-sets \
--hosted-zone-id 666666666666666666666 \
--change-batch file://a.json

 

aws route53 list-resource-record-sets \
--hosted-zone-id 666666666666666666666

 

-- プライベートホストゾーンの削除

aws route53 list-hosted-zones

aws route53 delete-hosted-zone \
--id 666666666666666666666

 

-- インスタンス削除

aws ec2 describe-instances

aws ec2 terminate-instances \
--instance-ids i-eeeeeeeeeeeeeeeee

 

 

-- インターネットゲートウェイ削除(VPCからデタッチしてから)

aws ec2 describe-internet-gateways
aws ec2 describe-internet-gateways | jq -r '.InternetGateways.InternetGatewayId'

aws ec2 detach-internet-gateway \
--internet-gateway-id igw-22222222222222222 \
--vpc-id vpc-11111111111111111

aws ec2 delete-internet-gateway \
--internet-gateway-id igw-22222222222222222


-- サブネット削除


aws ec2 describe-subnets
aws ec2 describe-subnets | jq -r '.Subnets.SubnetId'

aws ec2  delete-subnet \
--subnet-id subnet-44444444444444444

 


-- VPC削除

aws ec2  delete-vpc \
--vpc-id vpc-11111111111111111

aws ec2 describe-vpcs
aws ec2 describe-vpcs | jq -r '.Vpcs.VpcId'