2016-07-15 39 views
4

我有兩個表,productsproducts_names杜松子酒同時不在兩列上使用JOIN

我在做ILIKE兩列與GIN索引在兩個表中匹配,但只有在我只在一列上使用ILIKE時才使用GIN。

我做了一個解決辦法做聯盟但我想知道爲什麼它不工作,因爲我認爲它應該。

這兩列,n.namee.producer是VARCHAR對他們GIN指數:

CREATE INDEX products_producer_gin_idx ON products USING gin (producer gin_trgm_ops); 
CREATE INDEX products_names_name_gin_idx ON products_names USING gin (name gin_trgm_ops); 

與加入選擇和ILIKE這不使用GIN

testdb=# explain (analyze, verbose) 
      SELECT n.name, e.producer 
      FROM products e 
      INNER JOIN products_names n ON 
       n.product_id = e.product_id 

      WHERE 

        n.name ilike '%eda%' or e.producer ilike '%eda%' 


limit 20; 
                       QUERY PLAN                     
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
Limit (cost=0.42..2725.92 rows=20 width=60) (actual time=0.582..62.658 rows=20 loops=1) 
    Output: n.name, e.producer 
    -> Nested Loop (cost=0.42..669928.73 rows=4916 width=60) (actual time=0.582..62.652 rows=20 loops=1) 
     Output: n.name, e.producer 
     -> Seq Scan on public.products e (cost=0.00..220800.16 rows=446716 width=29) (actual time=0.002..5.363 rows=17067 loops=1) 
       Output: e.producer, e.product_id 
     -> Index Scan using products_names_pkey on public.products_names n (cost=0.42..1.00 rows=1 width=39) (actual time=0.003..0.003 rows=0 loops=17067) 
       Output: n.product_id, n.lang, n.name, n.name2, n.name3, n.products 
       Index Cond: (n.product_id = e.product_id) 
       Filter: (((n.name)::text ~~* '%eda%'::text) OR ((e.producer)::text ~~* '%eda%'::text)) 
       Rows Removed by Filter: 1 
Planning time: 0.559 ms 
Execution time: 62.677 ms 
(13 Zeilen) 

Zeit: 63,529 ms 

選擇一列n.name,其中使用GIN

testdb=# explain (analyze, verbose) 
      SELECT n.name, e.producer 
      FROM products e 
      INNER JOIN products_names n ON 
       n.product_id = e.product_id 

      WHERE 

        n.name ilike '%eda%'     

limit 20; 
                     QUERY PLAN                   
------------------------------------------------------------------------------------------------------------------------------------------------------------- 
Limit (cost=58.34..260.70 rows=20 width=60) (actual time=0.257..0.458 rows=20 loops=1) 
    Output: n.name, e.producer 
    -> Nested Loop (cost=58.34..49564.37 rows=4893 width=60) (actual time=0.256..0.454 rows=20 loops=1) 
     Output: n.name, e.producer 
     -> Bitmap Heap Scan on public.products_names n (cost=57.92..14890.29 rows=4893 width=39) (actual time=0.245..0.333 rows=20 loops=1) 
       Output: n.product_id, n.lang, n.name, n.name2, n.name3, n.products 
       Recheck Cond: ((n.name)::text ~~* '%eda%'::text) 
       Heap Blocks: exact=18 
       -> Bitmap Index Scan on products_names_name_gin_idx (cost=0.00..56.70 rows=4893 width=0) (actual time=0.160..0.160 rows=797 loops=1) 
        Index Cond: ((n.name)::text ~~* '%eda%'::text) 
     -> Index Scan using products_pkey on public.products e (cost=0.42..7.08 rows=1 width=29) (actual time=0.005..0.006 rows=1 loops=20) 
       Output: e.producer, e.product_id 
       Index Cond: (e.product_id = n.product_id) 
Planning time: 1.000 ms 
Execution time: 0.494 ms 
(15 Zeilen) 

Zeit: 2,563 ms 
+0

的[PostgreSQL的LIKE查詢性能的變化]可能的複製(http://stackoverflow.com/questions/1566717/postgresql-like-查詢性能變化) – e4c5

回答

0

這些只是周圍的工作。你可以推這個postgres來處理索引。

SELECT * from 
    (SELECT n.name, e.producer 
     FROM products e 
     INNER JOIN products_names n ON 
      n.product_id = e.product_id) a  
    WHERE 
      name ilike '%eda%' or producer ilike '%eda%' 

編輯 - 或者試試這個

SELECT * FROM 
    (SELECT n.name, e.producer 
     FROM products e 
     INNER JOIN products_names n ON 
      n.product_id = e.product_id 
     WHERE 
       n.name ilike '%eda%' )a 
    WHERE a.producer ilike '%eda%' 
+1

,根本不適合我。它不使用GIN,而且它甚至慢得多(3秒),可能是因爲內部SELECT基本上是將表與所有內容連接起來,然後ILIKE正在進行過濾。 – Beginner99

+0

你可以試試第二個。 – apm

+0

第二個作品,這是一個不錯的想法,但它提供了錯誤的結果,因爲內部選擇是按名稱過濾和生產者完全被忽略。如果沒有「eda」的製作人,沒有任何東西會被退回,這是不正確的 – Beginner99