Very slow query with PostgreSQL [closed] - postgresql

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 months ago.
Improve this question
I have a very serious problem with PostgreSQL 14. In practice, every 5 days or so my tables, or rather some, are corrupted. When I launch a simple query, it does not execute and it remains stuck.`enter code here`
This DB receives many write-to's in a day.
I think the table is corrupted. I would like to know why this happens if anyone has any ideas. Thank you all in advance.
I paste here an analyze that I did where I try to get the sum of some quantities in a month,
"QUERY PLAN"
"Aggregate (cost=109583.25..109583.26 rows=1 width=8) (actual time=138615.457..138628.145 rows=1 loops=1)"
" -> Gather (cost=69650.26..109583.25 rows=2 width=0) (actual time=138569.160..138626.750 rows=17950 loops=1)"
" Workers Planned: 2"
" Workers Launched: 2"
" -> Nested Loop (cost=68650.26..108583.05 rows=1 width=0) (actual time=138556.409..138599.546 rows=5983 loops=3)"
" Join Filter: (m.causale_id = caus.id)"
" Rows Removed by Join Filter: 154159"
" -> Parallel Hash Join (cost=68650.26..108581.15 rows=1 width=8) (actual time=138556.373..138560.611 rows=5983 loops=3)"
" Hash Cond: (rmdt.rigamovimentodettaglio_id = rmd.id)"
" -> Parallel Seq Scan on rigamovimentodettagliotaglia rmdt (cost=0.00..36254.00 rows=980500 width=8) (actual time=0.006..73.938 rows=784833 loops=3)"
" -> Parallel Hash (cost=68650.24..68650.24 rows=1 width=16) (actual time=138344.297..138344.300 rows=3414 loops=3)"
" Buckets: 16384 (originally 1024) Batches: 1 (originally 1) Memory Usage: 760kB"
" -> Hash Join (cost=35906.91..68650.24 rows=1 width=16) (actual time=137726.906..137728.106 rows=3414 loops=3)"
" Hash Cond: (rmd.rigamovimento_id = r.id)"
" -> Parallel Seq Scan on rigamovimentodettaglio rmd (cost=0.00..29574.42 rows=845042 width=16) (actual time=0.008..42.578 rows=676262 loops=3)"
" -> Hash (cost=35906.88..35906.88 rows=2 width=16) (actual time=137605.446..137605.448 rows=9221 loops=3)"
" Buckets: 16384 (originally 1024) Batches: 1 (originally 1) Memory Usage: 561kB"
" -> Nested Loop (cost=0.85..35906.88 rows=2 width=16) (actual time=39.893..137593.589 rows=9221 loops=3)"
" -> Index Scan using ukm9njdtmreayrcdjfln8chor0r on movimento m (cost=0.42..12620.62 rows=1 width=16) (actual time=0.085..32.738 rows=3290 loops=3)"
" Index Cond: ((datamovimento >= '2023-01-01'::date) AND (datamovimento <= '2023-02-01'::date))"
" -> Index Scan using uk_6iar6gjj0t1e0tq5g60a93wou on rigamovimento r (cost=0.43..23286.12 rows=15 width=16) (actual time=18.317..41.798 rows=3 loops=9870)"
" Index Cond: (movimento_id = m.id)"
" -> Seq Scan on causale caus (cost=0.00..1.40 rows=40 width=8) (actual time=0.001..0.003 rows=27 loops=17950)"
"Planning Time: 0.531 ms"
"JIT:"
" Functions: 86"
" Options: Inlining false, Optimization false, Expressions true, Deforming true"
" Timing: Generation 7.836 ms, Inlining 0.000 ms, Optimization 3.694 ms, Emission 54.204 ms, Total 65.733 ms"
"Execution Time: 138630.701 ms"
this is my configuration in db:
"allow_in_place_tablespaces" "off"
"allow_system_table_mods" "off"
"application_name" "pgAdmin 4 - CONN:8842897"
"archive_cleanup_command"
"archive_command" "(disabled)"
"archive_mode" "off"
"archive_timeout" "0"
"array_nulls" "on"
"authentication_timeout" "1min"
"autovacuum" "on"
"autovacuum_analyze_scale_factor" "0.1"
"autovacuum_analyze_threshold" "50"
"autovacuum_freeze_max_age" "200000000"
"autovacuum_max_workers" "3"
"autovacuum_multixact_freeze_max_age" "400000000"
"autovacuum_naptime" "1min"
"autovacuum_vacuum_cost_delay" "2ms"
"autovacuum_vacuum_cost_limit" "-1"
"autovacuum_vacuum_insert_scale_factor" "0.2"
"autovacuum_vacuum_insert_threshold" "1000"
"autovacuum_vacuum_scale_factor" "0.2"
"autovacuum_vacuum_threshold" "50"
"autovacuum_work_mem" "-1"
"backend_flush_after" "0"
"backslash_quote" "safe_encoding"
"backtrace_functions"
"bgwriter_delay" "200ms"
"bgwriter_flush_after" "512kB"
"bgwriter_lru_maxpages" "100"
"bgwriter_lru_multiplier" "2"
"block_size" "8192"
"bonjour" "off"
"bonjour_name"
"bytea_output" "hex"
"check_function_bodies" "on"
"checkpoint_completion_target" "0.9"
"checkpoint_flush_after" "256kB"
"checkpoint_timeout" "5min"
"checkpoint_warning" "30s"
"client_connection_check_interval" "0"
"client_encoding" "UNICODE"
"client_min_messages" "notice"
"cluster_name" "14/main"
"commit_delay" "0"
"commit_siblings" "5"
"compute_query_id" "auto"
"config_file" "/etc/postgresql/14/main/postgresql.conf"
"constraint_exclusion" "partition"
"cpu_index_tuple_cost" "0.005"
"cpu_operator_cost" "0.0025"
"cpu_tuple_cost" "0.01"
"cursor_tuple_fraction" "0.1"
"data_checksums" "off"
"data_directory" "/var/lib/postgresql/14/main"
"data_directory_mode" "0700"
"data_sync_retry" "off"
"DateStyle" "ISO, MDY"
"db_user_namespace" "off"
"deadlock_timeout" "1s"
"debug_assertions" "off"
"debug_discard_caches" "0"
"debug_pretty_print" "on"
"debug_print_parse" "off"
"debug_print_plan" "off"
"debug_print_rewritten" "off"
"default_statistics_target" "100"
"default_table_access_method" "heap"
"default_tablespace"
"default_text_search_config" "pg_catalog.english"
"default_toast_compression" "pglz"
"default_transaction_deferrable" "off"
"default_transaction_isolation" "read committed"
"default_transaction_read_only" "off"
"dynamic_library_path" "$libdir"
"dynamic_shared_memory_type" "posix"
"effective_cache_size" "3GB"
"effective_io_concurrency" "200"
"enable_async_append" "on"
"enable_bitmapscan" "on"
"enable_gathermerge" "on"
"enable_hashagg" "on"
"enable_hashjoin" "on"
"enable_incremental_sort" "on"
"enable_indexonlyscan" "on"
"enable_indexscan" "on"
"enable_material" "on"
"enable_memoize" "on"
"enable_mergejoin" "on"
"enable_nestloop" "on"
"enable_parallel_append" "on"
"enable_parallel_hash" "on"
"enable_partition_pruning" "on"
"enable_partitionwise_aggregate" "off"
"enable_partitionwise_join" "off"
"enable_seqscan" "on"
"enable_sort" "on"
"enable_tidscan" "on"
"escape_string_warning" "on"
"event_source" "PostgreSQL"
"exit_on_error" "off"
"extension_destdir"
"external_pid_file" "/var/run/postgresql/14-main.pid"
"extra_float_digits" "1"
"force_parallel_mode" "off"
"from_collapse_limit" "8"
"fsync" "on"
"full_page_writes" "on"
"geqo" "on"
"geqo_effort" "5"
"geqo_generations" "0"
"geqo_pool_size" "0"
"geqo_seed" "0"
"geqo_selection_bias" "2"
"geqo_threshold" "12"
"gin_fuzzy_search_limit" "0"
"gin_pending_list_limit" "4MB"
"hash_mem_multiplier" "1"
"hba_file" "/etc/postgresql/14/main/pg_hba.conf"
"hot_standby" "on"
"hot_standby_feedback" "off"
"huge_page_size" "0"
"huge_pages" "try"
"ident_file" "/etc/postgresql/14/main/pg_ident.conf"
"idle_in_transaction_session_timeout" "0"
"idle_session_timeout" "0"
"ignore_checksum_failure" "off"
"ignore_invalid_pages" "off"
"ignore_system_indexes" "off"
"in_hot_standby" "off"
"integer_datetimes" "on"
"IntervalStyle" "postgres"
"jit" "on"
"jit_above_cost" "100000"
"jit_debugging_support" "off"
"jit_dump_bitcode" "off"
"jit_expressions" "on"
"jit_inline_above_cost" "500000"
"jit_optimize_above_cost" "500000"
"jit_profiling_support" "off"
"jit_provider" "llvmjit"
"jit_tuple_deforming" "on"
"join_collapse_limit" "8"
"krb_caseins_users" "off"
"krb_server_keyfile" "FILE:/etc/postgresql-common/krb5.keytab"
"lc_collate" "C.UTF-8"
"lc_ctype" "C.UTF-8"
"lc_messages" "C.UTF-8"
"lc_monetary" "C.UTF-8"
"lc_numeric" "C.UTF-8"
"lc_time" "C.UTF-8"
"listen_addresses" "*"
"lo_compat_privileges" "off"
"local_preload_libraries"
"lock_timeout" "0"
"log_autovacuum_min_duration" "-1"
"log_checkpoints" "off"
"log_connections" "off"
"log_destination" "stderr"
"log_directory" "log"
"log_disconnections" "off"
"log_duration" "off"
"log_error_verbosity" "default"
"log_executor_stats" "off"
"log_file_mode" "0600"
"log_filename" "postgresql-%Y-%m-%d_%H%M%S.log"
"log_hostname" "off"
"log_line_prefix" "%m [%p] %q%u#%d "
"log_lock_waits" "off"
"log_min_duration_sample" "-1"
"log_min_duration_statement" "-1"
"log_min_error_statement" "error"
"log_min_messages" "warning"
"log_parameter_max_length" "-1"
"log_parameter_max_length_on_error" "0"
"log_parser_stats" "off"
"log_planner_stats" "off"
"log_recovery_conflict_waits" "off"
"log_replication_commands" "off"
"log_rotation_age" "1d"
"log_rotation_size" "10MB"
"log_statement" "none"
"log_statement_sample_rate" "1"
"log_statement_stats" "off"
"log_temp_files" "-1"
"log_timezone" "Europe/Rome"
"log_transaction_sample_rate" "0"
"log_truncate_on_rotation" "off"
"logging_collector" "off"
"logical_decoding_work_mem" "64MB"
"maintenance_io_concurrency" "10"
"maintenance_work_mem" "512MB"
"max_connections" "200"
"max_files_per_process" "1000"
"max_function_args" "100"
"max_identifier_length" "63"
"max_index_keys" "32"
"max_locks_per_transaction" "64"
"max_logical_replication_workers" "4"
"max_parallel_maintenance_workers" "2"
"max_parallel_workers" "4"
"max_parallel_workers_per_gather" "2"
"max_pred_locks_per_page" "2"
"max_pred_locks_per_relation" "-2"
"max_pred_locks_per_transaction" "64"
"max_prepared_transactions" "0"
"max_replication_slots" "10"
"max_slot_wal_keep_size" "-1"
"max_stack_depth" "2MB"
"max_standby_archive_delay" "30s"
"max_standby_streaming_delay" "30s"
"max_sync_workers_per_subscription" "2"
"max_wal_senders" "10"
"max_wal_size" "4GB"
"max_worker_processes" "4"
"min_dynamic_shared_memory" "0"
"min_parallel_index_scan_size" "512kB"
"min_parallel_table_scan_size" "8MB"
"min_wal_size" "1GB"
"old_snapshot_threshold" "-1"
"parallel_leader_participation" "on"
"parallel_setup_cost" "1000"
"parallel_tuple_cost" "0.1"
"password_encryption" "scram-sha-256"
"plan_cache_mode" "auto"
"port" "5432"
"post_auth_delay" "0"
"pre_auth_delay" "0"
"primary_conninfo"
"primary_slot_name"
"promote_trigger_file"
"quote_all_identifiers" "off"
"random_page_cost" "1.1"
"recovery_end_command"
"recovery_init_sync_method" "fsync"
"recovery_min_apply_delay" "0"
"recovery_target"
"recovery_target_action" "pause"
"recovery_target_inclusive" "on"
"recovery_target_lsn"
"recovery_target_name"
"recovery_target_time"
"recovery_target_timeline" "latest"
"recovery_target_xid"
"remove_temp_files_after_crash" "on"
"restart_after_crash" "on"
"restore_command"
"row_security" "on"
"search_path" """$user"", public"
"segment_size" "1GB"
"seq_page_cost" "1"
"server_encoding" "UTF8"
"server_version" "14.6 (Ubuntu 14.6-1.pgdg18.04+1)"
"server_version_num" "140006"
"session_preload_libraries"
"session_replication_role" "origin"
"shared_buffers" "1GB"
"shared_memory_type" "mmap"
"shared_preload_libraries"
"ssl" "on"
"ssl_ca_file"
"ssl_cert_file" "/etc/ssl/certs/ssl-cert-snakeoil.pem"
"ssl_ciphers" "HIGH:MEDIUM:+3DES:!aNULL"
"ssl_crl_dir"
"ssl_crl_file"
"ssl_dh_params_file"
"ssl_ecdh_curve" "prime256v1"
"ssl_key_file" "/etc/ssl/private/ssl-cert-snakeoil.key"
"ssl_library" "OpenSSL"
"ssl_max_protocol_version"
"ssl_min_protocol_version" "TLSv1.2"
"ssl_passphrase_command"
"ssl_passphrase_command_supports_reload" "off"
"ssl_prefer_server_ciphers" "on"
"standard_conforming_strings" "on"
"statement_timeout" "0"
"stats_temp_directory" "/var/run/postgresql/14-main.pg_stat_tmp"
"superuser_reserved_connections" "3"
"synchronize_seqscans" "on"
"synchronous_commit" "on"
"synchronous_standby_names"
"syslog_facility" "local0"
"syslog_ident" "postgres"
"syslog_sequence_numbers" "on"
"syslog_split_messages" "on"
"tcp_keepalives_count" "9"
"tcp_keepalives_idle" "7200"
"tcp_keepalives_interval" "75"
"tcp_user_timeout" "0"
"temp_buffers" "8MB"
"temp_file_limit" "-1"
"temp_tablespaces"
"TimeZone" "Europe/Rome"
"timezone_abbreviations" "Default"
"trace_notify" "off"
"trace_recovery_messages" "log"
"trace_sort" "off"
"track_activities" "on"
"track_activity_query_size" "1kB"
"track_commit_timestamp" "off"
"track_counts" "on"
"track_functions" "none"
"track_io_timing" "off"
"track_wal_io_timing" "off"
"transaction_deferrable" "off"
"transaction_isolation" "read committed"
"transaction_read_only" "off"
"transform_null_equals" "off"
"unix_socket_directories" "/var/run/postgresql"
"unix_socket_group"
"unix_socket_permissions" "0777"
"update_process_title" "on"
"vacuum_cost_delay" "0"
"vacuum_cost_limit" "200"
"vacuum_cost_page_dirty" "20"
"vacuum_cost_page_hit" "1"
"vacuum_cost_page_miss" "2"
"vacuum_defer_cleanup_age" "0"
"vacuum_failsafe_age" "1600000000"
"vacuum_freeze_min_age" "50000000"
"vacuum_freeze_table_age" "150000000"
"vacuum_multixact_failsafe_age" "1600000000"
"vacuum_multixact_freeze_min_age" "5000000"
"vacuum_multixact_freeze_table_age" "150000000"
"wal_block_size" "8192"
"wal_buffers" "16MB"
"wal_compression" "off"
"wal_consistency_checking"
"wal_init_zero" "on"
"wal_keep_size" "0"
"wal_level" "replica"
"wal_log_hints" "off"
"wal_receiver_create_temp_slot" "off"
"wal_receiver_status_interval" "10s"
"wal_receiver_timeout" "1min"
"wal_recycle" "on"
"wal_retrieve_retry_interval" "5s"
"wal_segment_size" "16MB"
"wal_sender_timeout" "1min"
"wal_skip_threshold" "2MB"
"wal_sync_method" "fdatasync"
"wal_writer_delay" "200ms"
"wal_writer_flush_after" "1MB"
"work_mem" "2621kB"
"xmlbinary" "base64"
"xmloption" "content"
"zero_damaged_pages" "off"

Related

psql: Sequential scan used instead of index when searching on tsvector tokens

There seems to be a threshold crossed where searching on enough keywords, the query starts using a sequential scan instead of the index.
Is there any way around this, or a way to speed this up?
This query:
SELECT ID
FROM people
WHERE
(( title_tokens
##
websearch_to_tsquery(
'simple',
'sales or commercial')
))
Appears to use the index:
[["Bitmap Heap Scan on people (cost=1546.20..325792.66 rows=164929 width=8)"],
[" Recheck Cond: (title_tokens ## '''sales'' | ''commercial'''::tsquery)"],
[" -> Bitmap Index Scan on index_people_on_title_tokens (cost=0.00..1504.97 rows=164929 width=0)"],
[" Index Cond: (title_tokens ## '''sales'' | ''commercial'''::tsquery)"],
["JIT:"],
[" Functions: 4"],
[" Options: Inlining false, Optimization false, Expressions true, Deforming true"]]>
However, this query:
SELECT ID
FROM people
WHERE
(( title_tokens
##
websearch_to_tsquery(
'simple',
'sales or commercial or growth or demand or gen or gtm or cmo or chief or founder or ceo or gm')
))
Uses a sequential scan:
[["Seq Scan on people (cost=0.00..402871.58 rows=392222 width=8)"],
[" Filter: (title_tokens ## '''sales'' | ''commercial'' | ''growth'' | ''demand'' | ''gen'' | ''gtm'' | ''cmo'' | ''chief'' | ''founder'' | ''ceo'' | ''gm'''::tsquery)"],
["JIT:"],
[" Functions: 4"],
[" Options: Inlining false, Optimization false, Expressions true, Deforming true"]]>

Simple batch DELETE then INSERT procedure some 1000 times slower than executing the statements one after the other

In arather simple table with an composite primary key (see DDL) there are about 40k records.
create table la_ezg
(
be_id integer not null,
usage text not null,
area numeric(18, 6),
sk_area numeric(18, 6),
count_ezg numeric(18, 6),
...
...
constraint la_ezg_pkey
primary key (be_id, usage)
);
There is also a simple procedure which purpose is to delete rows with a certain be_id and persist the rows from another view where they are "generated"
CREATE OR REPLACE function pr_create_la_ezg(pBE_ID numeric) returns void as
$$
begin
delete from la_ezg where be_id = pBE_ID;
insert into la_ezg_(BE_ID, USAGE, ...)
select be_id, usage, ...
from vw_la_ezg_with_usage
where be_id = pBE_ID;
END;
$$ language plpgsql;
The procedure need about 7 Minutes to execute...
Both Statements (DELETE and INSERT) execute in less than 100ms on the very same be_id.
There are a lot of different locks happening in pg_lock during that 7 Minutes but I wasn't able to figure out what exactly is going on inside this transaction and if there is some kind of deadlocking. After all the procedure is returning successful, but it needs way too much time doing it.
EDIT (activated 'auto_explain' and ran all three queries again):
duration: 1.420 ms plan:
Query Text: delete from la_ezg where be_id=790696
Delete on la_ezg (cost=4.33..22.89 rows=5 width=6)
-> Bitmap Heap Scan on la_ezg (cost=4.33..22.89 rows=5 width=6)
Output: ctid
Recheck Cond: (la_ezg.be_id = 790696)
-> Bitmap Index Scan on sys_c0073325 (cost=0.00..4.33 rows=5 width=0)
Index Cond: (la_ezg.be_id = 790696)
1 row affected in 107 ms
duration: 71.645 ms plan:
Query Text: insert into la_ezg(BE_ID,USAGE,...)
select be_id,USAGE,... from vw_la_ezg_with_usage where be_id=790696
Insert on la_ezg (cost=1343.71..2678.87 rows=1 width=228)
-> Nested Loop (cost=1343.71..2678.87 rows=1 width=228)
Output: la_ezg_geo.be_id, usage.nutzungsart, COALESCE(round(((COALESCE(st_area(la_ezg_geo.geometry), '3'::double precision) / '10000'::double precision))::numeric, 2), '0'::numeric), NULL::numeric, COALESCE((count(usage.nutzungsart)), '0'::bigint), COALESCE(round((((sum(st_area(st_intersection(ezg.geometry, usage.geom)))) / '10000'::double precision))::numeric, 2), '0'::numeric), COALESCE(round(((((sum(st_area(st_intersection(ezg.geometry, usage.geom)))) * '100'::double precision) / COALESCE(st_area(la_ezg_geo.geometry), '3'::double precision)))::numeric, 2), '0'::numeric), NULL::character varying, NULL::timestamp without time zone, NULL::character varying, NULL::timestamp without time zone
-> GroupAggregate (cost=1343.71..1343.76 rows=1 width=41)
Output: ezg.be_id, usage.nutzungsart, sum(st_area(st_intersection(ezg.geometry, usage.geom))), count(usage.nutzungsart)
Group Key: ezg.be_id, usage.nutzungsart
-> Sort (cost=1343.71..1343.71 rows=1 width=1834)
Output: ezg.be_id, usage.nutzungsart, ezg.geometry, usage.geom
Sort Key: usage.nutzungsart
-> Nested Loop (cost=0.42..1343.70 rows=1 width=1834)
Output: ezg.be_id, usage.nutzungsart, ezg.geometry, usage.geom
-> Seq Scan on la_ezg_geo ezg (cost=0.00..1335.00 rows=1 width=1516)
Output: ezg.objectid, ezg.be_id, ezg.name, ezg.se_anno_cad_data, ezg.benutzer_geaendert, ezg.datum_geaendert, ezg.status, ezg.benutzer_erstellt, ezg.datum_erstellt, ezg.len, ezg.geometry, ezg.temp_char, ezg.vulgo, ezg.flaeche, ezg.hauptgemeinde, ezg.prozessart, ezg.verbauungsgrad, ezg.verordnung_txt, ezg.gemeinden_txt, ezg.hinderungsgrund, ezg.kompetenz, ezg.seehoehe_min, ezg.seehoehe_max, ezg.neigung_min, ezg.neigung_max, ezg.exposition
Filter: (ezg.be_id = 790696)
-> Index Scan using dkm_nutz_fl_geom_1551355663100174000 on dkm.dkm_nutz_fl nutzung (cost=0.42..8.69 rows=1 width=318)
Output: usage.gdo_gid, usage.gst, usage.nutzungsart, usage.nutzungsabschnitt, usage.statistik, usage.flaeche, usage.kennung, usage.von_datum, usage.bis_datum, usage.von_az, usage.bis_az, usage.projekt, usage.fme_basename, usage.fme_dataset, usage.fme_feature_type, usage.fme_type, usage.oracle_srid, usage.geom
Index Cond: ((usage.geom && ezg.geometry) AND (usage.geom && ezg.geometry))
Filter: _st_intersects(usage.geom, ezg.geometry)
-> Seq Scan on la_ezg_geo (cost=0.00..1335.00 rows=1 width=1516)
Output: la_ezg_geo.objectid, la_ezg_geo.be_id, la_ezg_geo.name, la_ezg_geo.se_anno_cad_data, la_ezg_geo.benutzer_geaendert, la_ezg_geo.datum_geaendert, la_ezg_geo.status, la_ezg_geo.benutzer_erstellt, la_ezg_geo.datum_erstellt, la_ezg_geo.len, la_ezg_geo.geometry, la_ezg_geo.temp_char, la_ezg_geo.vulgo, la_ezg_geo.flaeche, la_ezg_geo.hauptgemeinde, la_ezg_geo.prozessart, la_ezg_geo.verbauungsgrad, la_ezg_geo.verordnung_txt, la_ezg_geo.gemeinden_txt, la_ezg_geo.hinderungsgrund, la_ezg_geo.kompetenz, la_ezg_geo.seehoehe_min, la_ezg_geo.seehoehe_max, la_ezg_geo.neigung_min, la_ezg_geo.neigung_max, la_ezg_geo.exposition
Filter: (la_ezg_geo.be_id = 790696)
1 row affected in 149 ms
duration: 421851.819 ms plan:
Query Text: select pr_create_la_ezg(790696)
Result (cost=0.00..0.26 rows=1 width=4)
Output: pr_create_la_ezg('790696'::numeric)
1 row retrieved starting from 1 in 7 m 1 s 955 ms (execution: 7 m 1 s 929 ms, fetching: 26 ms)
P.S. I shortened some of the queries and names for the sake of readability
P.P.S. This database is a legacy migration project. Like in this case there are often views dependent on views in multiple layers. I´d like to streamline all this but Ia m in a desperate need to debug whats going on inside such an transaction, otherwise I would have to rebuild nearly all with the risk of breaking things

Postgres cube type distance vector index slower than seq scan

With a 128 dimension column and a distance query as below:
CREATE TABLE testes (id serial, name text, face cube);
CREATE INDEX testes_face_idx ON testes USING gist(face gist_cube_ops);
explain analyse select name from testes order by face <-> cube(array[-0.12341737002134323, 0.013954268768429756, 0.041934967041015625, -0.027295179665088654, -0.1557110995054245, -0.03121102601289749, 0.017772752791643143, -0.17166048288345337, 0.09068921208381653, -0.13417541980743408, 0.17567767202854156, -0.06697715818881989, -0.1830156147480011, -0.08423275500535965, -0.0623091384768486, 0.13855493068695068, 0.01960853487253189, -0.12219744175672531, -0.1498851776123047, -0.1448814421892166, -0.04667501151561737, 0.10095512866973877, -0.010014703497290611, 0.028698112815618515, -0.12299459427595139, -0.2449578195810318, -0.04310397803783417, -0.0786057710647583, -0.0006230985745787621, -0.012474060989916325, -0.0008601928129792213, 0.13489803671836853, -0.17316003143787384, -0.056241780519485474, 0.04442238435149193, 0.14999067783355713, -0.04893124848604202, -0.03364997357130051, 0.17365986108779907, 0.014477224089205265, -0.14650581777095795, 0.06581126153469086, 0.05907478928565979, 0.24371813237667084, 0.199946790933609, -0.07071209698915482, 0.030652550980448723, -0.06517398357391357, 0.19778677821159363, -0.3098893463611603, 0.04202471300959587, 0.06682528555393219, 0.11922725290060043, 0.04458840191364288, 0.07993366569280624, -0.09807920455932617, -0.02106720767915249, 0.17947503924369812, -0.15518437325954437, 0.11362187564373016, 0.05837336927652359, -0.11214996874332428, -0.13685055077075958, -0.10379699617624283, 0.13636618852615356, 0.1293313056230545, -0.11564487218856812, -0.10860224068164825, 0.2200884073972702, -0.16025489568710327, -0.05225272849202156, 0.10024034976959229, -0.10087429732084274, -0.1339828222990036, -0.27345386147499084, 0.1377202421426773, 0.437569797039032, 0.17741253972053528, -0.18133604526519775, -0.052022092044353485, -0.03961575776338577, 0.07023612409830093, 0.013044891878962517, 0.007585287094116211, -0.015369717963039875, -0.13501259684562683, -0.07265347242355347, 0.011824256740510464, 0.21609637141227722, -0.012745738960802555, -0.04935416579246521, 0.23810920119285583, 0.031168460845947266, 0.034897398203611374, -0.014598412439227104, 0.0809953436255455, -0.11255790293216705, -0.06797720491886139, -0.09544365853071213, -0.008347772061824799, 0.0790143683552742, -0.11389575153589249, 0.046258144080638885, 0.12429731339216232, -0.15094317495822906, 0.24766354262828827, -0.10882335901260376, 0.022879034280776978, 0.03814130276441574, -0.013778979890048504, -0.01565537415444851, 0.07461182028055191, 0.14960512518882751, -0.15471796691417694, 0.18988533318042755, 0.10148166120052338, 0.0060581183061003685, 0.1403576135635376, 0.06793759763240814, 0.04792795702815056, 0.00046137627214193344, -0.007764225825667381, -0.15212640166282654, -0.18374276161193848, 0.03233196958899498, -0.05509287118911743, -0.0091116763651371, 0.06819846481084824]) limit 3;
Limit (cost=0.41..5.44 rows=3 width=18) (actual time=1557.082..1697.857 rows=3 loops=1)
-> Index Scan using testes_face_idx on testes (cost=0.41..1859319.05 rows=1109532 width=18) (actual time=1557.081..1697.855 rows=3 loops=1)
Order By: (face <-> '(-0.123417370021343, 0.0139542687684298, 0.0419349670410156, -0.0272951796650887, -0.155711099505424, -0.0312110260128975, 0.0177727527916431, -0.171660482883453, 0.0906892120838165, -0.134175419807434, 0.175677672028542, -0.0669771581888199, -0.183015614748001, -0.0842327550053596, -0.0623091384768486, 0.138554930686951, 0.0196085348725319, -0.122197441756725, -0.149885177612305, -0.144881442189217, -0.0466750115156174, 0.100955128669739, -0.0100147034972906, 0.0286981128156185, -0.122994594275951, -0.244957819581032, -0.0431039780378342, -0.0786057710647583, -0.000623098574578762, -0.0124740609899163, -0.000860192812979221, 0.134898036718369, -0.173160031437874, -0.0562417805194855, 0.0444223843514919, 0.149990677833557, -0.048931248486042, -0.0336499735713005, 0.173659861087799, 0.0144772240892053, -0.146505817770958, 0.0658112615346909, 0.0590747892856598, 0.243718132376671, 0.199946790933609, -0.0707120969891548, 0.0306525509804487, -0.0651739835739136, 0.197786778211594, -0.30988934636116, 0.0420247130095959, 0.0668252855539322, 0.1192272529006, 0.0445884019136429, 0.0799336656928062, -0.0980792045593262, -0.0210672076791525, 0.179475039243698, -0.155184373259544, 0.11362187564373, 0.0583733692765236, -0.112149968743324, -0.13685055077076, -0.103796996176243, 0.136366188526154, 0.129331305623055, -0.115644872188568, -0.108602240681648, 0.22008840739727, -0.160254895687103, -0.0522527284920216, 0.100240349769592, -0.100874297320843, -0.133982822299004, -0.273453861474991, 0.137720242142677, 0.437569797039032, 0.177412539720535, -0.181336045265198, -0.0520220920443535, -0.0396157577633858, 0.0702361240983009, 0.0130448918789625, 0.00758528709411621, -0.0153697179630399, -0.135012596845627, -0.0726534724235535, 0.0118242567405105, 0.216096371412277, -0.0127457389608026, -0.0493541657924652, 0.238109201192856, 0.0311684608459473, 0.0348973982036114, -0.0145984124392271, 0.0809953436255455, -0.112557902932167, -0.0679772049188614, -0.0954436585307121, -0.0083477720618248, 0.0790143683552742, -0.113895751535892, 0.0462581440806389, 0.124297313392162, -0.150943174958229, 0.247663542628288, -0.108823359012604, 0.022879034280777, 0.0381413027644157, -0.0137789798900485, -0.0156553741544485, 0.0746118202805519, 0.149605125188828, -0.154717966914177, 0.189885333180428, 0.101481661200523, 0.00605811830610037, 0.140357613563538, 0.0679375976324081, 0.0479279570281506, 0.000461376272141933, -0.00776422582566738, -0.152126401662827, -0.183742761611938, 0.032331969588995, -0.0550928711891174, -0.0091116763651371, 0.0681984648108482)'::cube)
Planning time: 0.101 ms
Execution time: 1698.691 ms
Then I dropped the index and now it is faster:
Limit (cost=186715.64..186715.65 rows=3 width=18) (actual time=1362.653..1362.667 rows=3 loops=1)
-> Sort (cost=186715.64..189489.47 rows=1109532 width=18) (actual time=1362.652..1362.652 rows=3 loops=1)
Sort Key: ((face <-> '(-0.123417370021343, 0.0139542687684298, 0.0419349670410156, -0.0272951796650887, -0.155711099505424, -0.0312110260128975, 0.0177727527916431, -0.171660482883453, 0.0906892120838165, -0.134175419807434, 0.175677672028542, -0.0669771581888199, -0.183015614748001, -0.0842327550053596, -0.0623091384768486, 0.138554930686951, 0.0196085348725319, -0.122197441756725, -0.149885177612305, -0.144881442189217, -0.0466750115156174, 0.100955128669739, -0.0100147034972906, 0.0286981128156185, -0.122994594275951, -0.244957819581032, -0.0431039780378342, -0.0786057710647583, -0.000623098574578762, -0.0124740609899163, -0.000860192812979221, 0.134898036718369, -0.173160031437874, -0.0562417805194855, 0.0444223843514919, 0.149990677833557, -0.048931248486042, -0.0336499735713005, 0.173659861087799, 0.0144772240892053, -0.146505817770958, 0.0658112615346909, 0.0590747892856598, 0.243718132376671, 0.199946790933609, -0.0707120969891548, 0.0306525509804487, -0.0651739835739136, 0.197786778211594, -0.30988934636116, 0.0420247130095959, 0.0668252855539322, 0.1192272529006, 0.0445884019136429, 0.0799336656928062, -0.0980792045593262, -0.0210672076791525, 0.179475039243698, -0.155184373259544, 0.11362187564373, 0.0583733692765236, -0.112149968743324, -0.13685055077076, -0.103796996176243, 0.136366188526154, 0.129331305623055, -0.115644872188568, -0.108602240681648, 0.22008840739727, -0.160254895687103, -0.0522527284920216, 0.100240349769592, -0.100874297320843, -0.133982822299004, -0.273453861474991, 0.137720242142677, 0.437569797039032, 0.177412539720535, -0.181336045265198, -0.0520220920443535, -0.0396157577633858, 0.0702361240983009, 0.0130448918789625, 0.00758528709411621, -0.0153697179630399, -0.135012596845627, -0.0726534724235535, 0.0118242567405105, 0.216096371412277, -0.0127457389608026, -0.0493541657924652, 0.238109201192856, 0.0311684608459473, 0.0348973982036114, -0.0145984124392271, 0.0809953436255455, -0.112557902932167, -0.0679772049188614, -0.0954436585307121, -0.0083477720618248, 0.0790143683552742, -0.113895751535892, 0.0462581440806389, 0.124297313392162, -0.150943174958229, 0.247663542628288, -0.108823359012604, 0.022879034280777, 0.0381413027644157, -0.0137789798900485, -0.0156553741544485, 0.0746118202805519, 0.149605125188828, -0.154717966914177, 0.189885333180428, 0.101481661200523, 0.00605811830610037, 0.140357613563538, 0.0679375976324081, 0.0479279570281506, 0.000461376272141933, -0.00776422582566738, -0.152126401662827, -0.183742761611938, 0.032331969588995, -0.0550928711891174, -0.0091116763651371, 0.0681984648108482)'::cube))
Sort Method: top-N heapsort Memory: 25kB
-> Seq Scan on testes (cost=0.00..172375.15 rows=1109532 width=18) (actual time=0.006..1239.698 rows=1109532 loops=1)
Planning time: 0.112 ms
Execution time: 1362.681 ms
Any ideas where to start debugging this? The time difference holds from 100k row to 1.1M rows.
Is it possible that it relates to the "high" 128 dimensions?

plpgsql function calling trigram similarity function inside does not utilize GIN or GIST indexes

I wanted to combine PostgreSQL Levenshtein and trigram similarity functions.
The main advantage of the trigram similarity function is that it can utilize GIN or GIST indexes and thus can return fuzzy match results quickly. However, if it is called inside another function, it does not use indexes.
For sake of this problem illustration, here is a plpgsql function "trigram_similarity" that calls original trigram's "similarity" function.
CREATE OR REPLACE FUNCTION public.trigram_similarity(
left_string text,
right_string text)
RETURNS real AS
$BODY$
BEGIN
RETURN similarity(left_string, right_string);
END;$BODY$
LANGUAGE plpgsql IMMUTABLE STRICT
COST 100;
ALTER FUNCTION public.trigram_similarity(text, text)
OWNER TO postgres;
Although the function actually just calls the trigram's similarity function, it behaves completely different when it comes to GIN indexes utilization. While the original trigram's similarity function inside WHERE clause of a query does utilize GIN indexes and thus a query returns result quickly and without much RAM consumption, when using trigram_similarity it does not. For large datasets fuzzy match analysis, the RAM is completely used and application freezes...
For sake of illustration, here is an example query:
SELECT DISTINCT
trigram_similarity(l.l_composite_18, r.r_composite_18)
::numeric(5,4) AS trigram_similarity_composite_score
, (trigram_similarity(l."Name", r."Name")*(0.166666666666667)
+ trigram_similarity(l."LastName", r."Surname")*(0.0833333333333333)
+ trigram_similarity(l."County", r."District")*(0.0416666666666667)
+ trigram_similarity(l."Town", r."Location")*(0.0416666666666667)
+ trigram_similarity(l."PostalCode", r."ZipCode")*(0.0416666666666667)
+ trigram_similarity(l."PostOffice", r."PostOffice")*(0.0416666666666667)
+ trigram_similarity(l."Street", r."Road")*(0.0416666666666667)
+ trigram_similarity(l."Number", r."HomeNumber")*(0.0416666666666667)
+ trigram_similarity(l."Telephone1", r."Phone1")*(0.0416666666666667)
+ trigram_similarity(l."Telephone2", r."Phone2")*(0.0416666666666667)
+ trigram_similarity(l."EMail", r."EMail")*(0.0416666666666667)
+ trigram_similarity(l."BirthDate", r."DateOfBirth")*(0.166666666666667)
+ trigram_similarity(l."Gender", r."Sex")*(0.208333333333333)
)
::numeric(5,4) AS trigram_similarity_weighted_score
, l."ClanID" AS "l_ClanID_1"
, l."Name" AS "l_Name_2"
, l."LastName" AS "l_LastName_3"
, l."County" AS "l_County_4"
, l."Town" AS "l_Town_5"
, l."PostalCode" AS "l_PostalCode_6"
, l."PostOffice" AS "l_PostOffice_7"
, l."Street" AS "l_Street_8"
, l."Number" AS "l_Number_9"
, l."Telephone1" AS "l_Telephone1_10"
, l."Telephone2" AS "l_Telephone2_11"
, l."EMail" AS "l_EMail_12"
, l."BirthDate" AS "l_BirthDate_13"
, l."Gender" AS "l_Gender_14"
, l."Aktivan" AS "l_Aktivan_15"
, l."ProgramCode" AS "l_ProgramCode_16"
, l."Card" AS "l_Card_17"
, l."DateOfCreation" AS "l_DateOfCreation_18"
, l."Assigned" AS "l_Assigned_19"
, l."Reserved" AS "l_Reserved_20"
, l."Sent" AS "l_Sent_21"
, l."MemberOfBothPrograms" AS "l_MemberOfBothPrograms_22"
, r."ClanID" AS "r_ClanID_23"
, r."Name" AS "r_Name_24"
, r."Surname" AS "r_Surname_25"
, r."District" AS "r_District_26"
, r."Location" AS "r_Location_27"
, r."ZipCode" AS "r_ZipCode_28"
, r."PostOffice" AS "r_PostOffice_29"
, r."Road" AS "r_Road_30"
, r."HomeNumber" AS "r_HomeNumber_31"
, r."Phone1" AS "r_Phone1_32"
, r."Phone2" AS "r_Phone2_33"
, r."EMail" AS "r_EMail_34"
, r."DateOfBirth" AS "r_DateOfBirth_35"
, r."Sex" AS "r_Sex_36"
, r."Active" AS "r_Active_37"
, r."ProgramCode" AS "r_ProgramCode_38"
, r."CardNo" AS "r_CardNo_39"
, r."CreationDate" AS "r_CreationDate_40"
, r."Assigned" AS "r_Assigned_41"
, r."Reserved" AS "r_Reserved_42"
, r."Sent" AS "r_Sent_43"
, r."BothPrograms" AS "r_BothPrograms_44"
FROM "l_leftdatasetexample3214274191" AS l, "r_rightdatasetexample3214274191" AS r
WHERE
((l."Gender"=r."Sex") AND (l."Card"<>r."CardNo") AND (l."Name"=r."Name"))
AND
((l."ProgramCode"= '1') AND (r."ProgramCode"= '1'))
AND
(((l.l_composite_18 % r.r_composite_18)
)
OR (((l."Name" % r."Name")
OR (l."LastName" % r."Surname")
OR (l."County" % r."District")
OR (l."Town" % r."Location")
OR (l."PostalCode" % r."ZipCode")
OR (l."PostOffice" % r."PostOffice")
OR (l."Street" % r."Road")
OR (l."Number" % r."HomeNumber")
OR (l."Telephone1" % r."Phone1")
OR (l."Telephone2" % r."Phone2")
OR (l."EMail" % r."EMail")
OR (l."BirthDate" % r."DateOfBirth")
OR (l."Gender" % r."Sex"))
)
) AND ((trigram_similarity(l.l_composite_18, r.r_composite_18)
>= 0.7)
OR ((trigram_similarity(l."Name", r."Name")*(0.166666666666667)
+ trigram_similarity(l."LastName", r."Surname")*(0.0833333333333333)
+ trigram_similarity(l."County", r."District")*(0.0416666666666667)
+ trigram_similarity(l."Town", r."Location")*(0.0416666666666667)
+ trigram_similarity(l."PostalCode", r."ZipCode")*(0.0416666666666667)
+ trigram_similarity(l."PostOffice", r."PostOffice")*(0.0416666666666667)
+ trigram_similarity(l."Street", r."Road")*(0.0416666666666667)
+ trigram_similarity(l."Number", r."HomeNumber")*(0.0416666666666667)
+ trigram_similarity(l."Telephone1", r."Phone1")*(0.0416666666666667)
+ trigram_similarity(l."Telephone2", r."Phone2")*(0.0416666666666667)
+ trigram_similarity(l."EMail", r."EMail")*(0.0416666666666667)
+ trigram_similarity(l."BirthDate", r."DateOfBirth")*(0.166666666666667)
+ trigram_similarity(l."Gender", r."Sex")*(0.208333333333333)
)
>= 0.7)
) ORDER BY trigram_similarity_composite_score DESC;
This query causes RAM clottage and application freezes. When "trigram_similarity" is replaced with "similarity", the query executes fast and without RAM overconsumption.
Why "trigram_similarity" and "similarity" behave differently?
Is there a way I could force GIN or GIST indexes utilization for this "trigram_similarity" function or any other function calling trigram's similarity function inside?
Explain analyze when "similarity" is used:
"Unique (cost=170717.94..177633.17 rows=58853 width=383) (actual time=260362.193..260362.279 rows=99 loops=1)"
" Output: ((similarity((l.l_composite_18)::text, (r.r_composite_18)::text))::numeric(5,4)), (((((((((((((((similarity((l."Name")::text, (r."Name")::text) * '0.166666666666667'::double precision) + (similarity((l."LastName")::text, (r."Surname")::text) * '0 (...)"
" Buffers: shared hit=2513871 read=4158"
" -> Sort (cost=170717.94..170865.07 rows=58853 width=383) (actual time=260362.192..260362.198 rows=99 loops=1)"
" Output: ((similarity((l.l_composite_18)::text, (r.r_composite_18)::text))::numeric(5,4)), (((((((((((((((similarity((l."Name")::text, (r."Name")::text) * '0.166666666666667'::double precision) + (similarity((l."LastName")::text, (r."Surname")::text (...)"
" Sort Key: ((similarity((l.l_composite_18)::text, (r.r_composite_18)::text))::numeric(5,4)) DESC, (((((((((((((((similarity((l."Name")::text, (r."Name")::text) * '0.166666666666667'::double precision) + (similarity((l."LastName")::text, (r."Surname" (...)"
" Sort Method: quicksort Memory: 76kB"
" Buffers: shared hit=2513871 read=4158"
" -> Nested Loop (cost=0.29..155793.36 rows=58853 width=383) (actual time=1851.503..260361.609 rows=99 loops=1)"
" Output: (similarity((l.l_composite_18)::text, (r.r_composite_18)::text))::numeric(5,4), ((((((((((((((similarity((l."Name")::text, (r."Name")::text) * '0.166666666666667'::double precision) + (similarity((l."LastName")::text, (r."Surname")::t (...)"
" Buffers: shared hit=2513871 read=4158"
" -> Seq Scan on public.r_rightdatasetexample3214274191 r (cost=0.00..11228.86 rows=101669 width=188) (actual time=9.149..67.134 rows=50837 loops=1)"
" Output: r."ClanID", r."Name", r."Surname", r."District", r."Location", r."ZipCode", r."PostOffice", r."Road", r."HomeNumber", r."Phone1", r."Phone2", r."EMail", r."DateOfBirth", r."Sex", r."Active", r."ProgramCode", r."CardNo", r."Creat (...)"
" Filter: ((r."ProgramCode")::text = '1'::text)"
" Buffers: shared hit=5800 read=4158"
" -> Index Scan using "idxbNameA8D72F00099E4B70885B2E0BB1DFB684l_leftdatasetexample321" on public.l_leftdatasetexample3214274191 l (cost=0.29..1.35 rows=1 width=195) (actual time=5.111..5.119 rows=0 loops=50837)"
" Output: l."ClanID", l."Name", l."LastName", l."County", l."Town", l."PostalCode", l."PostOffice", l."Street", l."Number", l."Telephone1", l."Telephone2", l."EMail", l."BirthDate", l."Gender", l."Aktivan", l."ProgramCode", l."Card", l."D (...)"
" Index Cond: ((l."Name")::text = (r."Name")::text)"
" Filter: (((l."ProgramCode")::text = '1'::text) AND ((l."Card")::text <> (r."CardNo")::text) AND ((r."Sex")::text = (l."Gender")::text) AND (((l.l_composite_18)::text % (r.r_composite_18)::text) OR ((l."Name")::text % (r."Name")::text) O (...)"
" Rows Removed by Filter: 50"
" Buffers: shared hit=2508071"
"Planning time: 13.885 ms"
"Execution time: 260362.730 ms"
The indices are created on table columns. You need to modify your plpgsql function to query a GIN- or GIST-indexed, table column rather than comparing two, string literals. If you compare two, string literals the plugin has no index to hit and must decompose both strings into their trigrams before comparing them, which is your problem.
http://www.postgresql.org/docs/9.1/static/pgtrgm.html
It is possible to create GIN trgm_ops expression index on the compound (concatenated) expression. This index can faciliate % similarity operator, but not the similarity function.

postgresql- slow update query

I'm working with a table that has about 19 million rows and 60 columns (bigtable). Of the 19 million records, about 17 million have x and y coordinates (about 1.8 million distinct combinations of x and y). I needed to add some additional geocoded information to the table from another file (census_geocode). I've created a lookup table (distinct_xy) that has a list of all the distinct x and y coordinate pairs and an ID. I have indexes on bigtable (x_coord, y_coord), census_geocode (x_coord, y_coord), and distinct_xy (x_coord, y_coord), and a primary key in distinct_xy (xy_id) and census_geocode (xy_id). So here's the query:
Update bigtable
set block_grp = cg.blkgrp,
block = cg.block,
tract = cg.tractce10
from census_geocode cg, distinct_xy xy
where bigtable.x_coord = xy.x_coord and
bigtable.y_coord=xy.y_coord and cg.xy_id=xy.xy_id;
This is running extremely slowly. as in:
"Update on bigtable (cost=17675751.51..17827040.74 rows=22 width=327)"
" -> Nested Loop (cost=17675751.51..17827040.74 rows=22 width=327)"
" -> Merge Join (cost=17675751.51..17826856.26 rows=22 width=312)"
" Merge Cond: ((bigtable.x_coord = xy.x_coord) AND (bigtable.y_coord = xy.y_coord))"
" -> Sort (cost=17318145.58..17366400.81 rows=19302092 width=302)"
" Sort Key: bigtable.x_coord, bigtable.y_coord"
" -> Seq Scan on bigtable (cost=0.00..1457709.92 rows=19302092 width=302)"
" -> Materialize (cost=357588.42..366887.02 rows=1859720 width=26)"
" -> Sort (cost=357588.42..362237.72 rows=1859720 width=26)"
" Sort Key: xy.x_coord, xy.y_coord"
" -> Seq Scan on distinct_xy xy (cost=0.00..30443.20 rows=1859720 width=26)"
" -> Index Scan using census_geocode_pkey on census_geocode cg (cost=0.00..8.37 rows=1 width=23)"
" Index Cond: (xy_id = xy.xy_id)"
I've also tried splitting this apart and inserting the lookup key back into the big table to avoid the multi-table join.
Update bigtable
set xy_id = xy.xy_id
from distinct_xy xy
where bigtable.x_coord = xy.x_coord and bigtable.y_coord=xy.y_coord;
this also runs for hours without completing.
"Update on bigtable (cost=0.00..20577101.71 rows=22 width=404)"
" -> Nested Loop (cost=0.00..20577101.71 rows=22 width=404)"
" -> Seq Scan on distinct_xy xy (cost=0.00..30443.20 rows=1859720 width=26)"
" -> Index Scan using rae_xy_idx on bigtable (cost=0.00..11.03 rows=1 width=394)"
" Index Cond: ((x_coord = xy.x_coord) AND (y_coord = xy.y_coord))"
Can someone please help me improve this query's performance?