indeksy, wyszukiwanie rekordów przy dużej ilości warunków

0

Mam taką tabelę:

CREATE TABLE "public"."side_quests" (
  "q_id" SERIAL, 
  "q_name" VARCHAR(50) NOT NULL, 
  "q_map_object" "public"."object", 
  "q_map_surface" "public"."surface", 
  "q_real_time" TIME WITHOUT TIME ZONE[], 
  "q_game_time" VARCHAR(8)[], 
  "q_map_position" POINT, 
  "q_on_enemys_field" BOOLEAN, 
  "q_for_adult" BOOLEAN DEFAULT false NOT NULL, 
  "q_chance" INTEGER DEFAULT 100 NOT NULL, 
  "q_on_border" BOOLEAN, 
  "q_for_premium" BOOLEAN DEFAULT false NOT NULL, 
  CONSTRAINT "quests_pkey" PRIMARY KEY("q_id")
) WITHOUT OIDS;

i takie zapytanie szukające

SELECT sq.q_id INTO quest_id FROM side_quests sq,
(SELECT m.m_position, m.m_object, m.m_surface, m.m_kingdom, m.m_is_border FROM map m WHERE m.m_position = POINT(pos[1], pos[2]) LIMIT 1) m,
(SELECT u.u_kingdom, u_premium FROM users u WHERE u.u_id = user_id LIMIT 1) u,
(SELECT (d.d_hour||':'||EXTRACT(MINUTE FROM now()::time)||':'||EXTRACT(SECOND FROM now()::time)) d_time FROM "date" d LIMIT 1) d
WHERE (CASE sq.q_map_object WHEN m.m_object THEN TRUE ELSE FALSE END OR sq.q_map_object IS NULL) AND
(CASE sq.q_map_surface WHEN m.m_surface THEN TRUE ELSE FALSE END OR sq.q_map_surface IS NULL) AND
(sq.q_map_position IS NULL OR sq.q_map_position = m.m_position) AND
(sq.q_on_border IS NULL OR sq.q_on_border = m.m_is_border) AND
(sq.q_on_enemys_field IS NULL OR CASE sq.q_on_enemys_field WHEN TRUE THEN (u.u_kingdom != m.m_kingdom) WHEN FALSE THEN (u.u_kingdom = m.m_kingdom) END) AND
(sq.q_real_time IS NULL OR (now()::time >= sq.q_real_time[1] AND now()::time <= sq.q_real_time[2])) AND
(sq.q_game_time IS NULL OR (d.d_time >= sq.q_game_time[1] AND d.d_time <= sq.q_game_time[2])) AND
(sq.q_for_premium = FALSE OR u.u_premium > now()::abstime::integer) AND
rand(1, 100) < sq.q_chance
ORDER BY RANDOM() LIMIT 1;

I nie wiem jakie dać indeksy do tabeli, żeby przy wyszukiwaniu przy dużej ilości rekordów baza się nie posypała. Mam nadzieję, że zapytanie choć długie jest zrozumiałe, jak coś to pytać. Jak ktoś ma pomysł na wydajniejsze zapytanie to też bym był wdzięczny.

0

zrób najpierw na polu, które odsieje najwięcej danych i zawsze jest po nim filtrowanie, potem po tym, które odsieje najwięcej z tych już odsianych itd. Po każdej zmianie indeksu odpalasz zapytanie i sprawdzasz w planie czy lepiej czy gorzej

1 użytkowników online, w tym zalogowanych: 0, gości: 1