From b6acbc77f10cd9c8bc41b28e229cffcecb36d62f Mon Sep 17 00:00:00 2001 From: Weimin Yu Date: Wed, 9 Mar 2022 23:32:17 -0500 Subject: [PATCH] Revise host.inet_addresses query to use gin index (#1550) * Revise host.inet_addresses query to use gin index --- .../java/google/registry/model/host/HostResource.java | 11 +++++++++++ .../registry/whois/NameserverLookupByIpCommand.java | 10 ++++++++-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/google/registry/model/host/HostResource.java b/core/src/main/java/google/registry/model/host/HostResource.java index 27cc43e6f..a1c876490 100644 --- a/core/src/main/java/google/registry/model/host/HostResource.java +++ b/core/src/main/java/google/registry/model/host/HostResource.java @@ -36,6 +36,17 @@ import javax.persistence.AccessType; @javax.persistence.Entity(name = "Host") @javax.persistence.Table( name = "Host", + /** + * A gin index defined on the inet_addresses field ({@link HostBase#inetAddresses} cannot be + * declared here because JPA/Hibernate does not support index type specification. As a result, + * the hibernate-generated schema (which is for reference only) does not have this index. + * + *

There are Hibernate-specific solutions for adding this index to Hibernate's domain model. + * We could either declare the index in hibernate.cfg.xml or add it to the {@link + * org.hibernate.cfg.Configuration} instance for {@link SessionFactory} instantiation (which + * would prevent us from using JPA standard bootstrapping). For now, there is no obvious benefit + * doing either. + */ indexes = {@javax.persistence.Index(columnList = "hostName")}) @ExternalMessagingName("host") @WithStringVKey diff --git a/core/src/main/java/google/registry/whois/NameserverLookupByIpCommand.java b/core/src/main/java/google/registry/whois/NameserverLookupByIpCommand.java index bb086de24..a0fc736b6 100644 --- a/core/src/main/java/google/registry/whois/NameserverLookupByIpCommand.java +++ b/core/src/main/java/google/registry/whois/NameserverLookupByIpCommand.java @@ -64,11 +64,17 @@ final class NameserverLookupByIpCommand implements WhoisCommand { jpaTm() .transact( () -> - // We cannot query @Convert-ed fields in HQL so we must use native Postgres + // We cannot query @Convert-ed fields in HQL so we must use native Postgres. jpaTm() .getEntityManager() + /** + * Using array_operator <@ (contained-by) with gin index on inet_address. + * Without gin index, this is slightly slower than the alternative form of + * ':address = ANY(inet_address)'. + */ .createNativeQuery( - "SELECT * From \"Host\" WHERE :address = ANY(inet_addresses) AND " + "SELECT * From \"Host\" WHERE " + + "ARRAY[ CAST(:address AS TEXT) ] <@ inet_addresses AND " + "deletion_time > CAST(:now AS timestamptz)", HostResource.class) .setParameter("address", InetAddresses.toAddrString(ipAddress))