2016-07-28 13 views
1

Ich habe Rails-Anwendung mit der Fähigkeit, Datensätze durch state_code zu filtern. Ich habe bemerkt, dass wenn ich 'CA' als Suchbegriff übergebe, ich meine Ergebnisse fast sofort bekomme. Wenn ich zum Beispiel 'AZ' übergebe, dauert es mehr als eine Minute.1 Minute Unterschied in fast identische PostgreSQL-Abfragen?

Ich habe keine Ideen warum so?

Im Folgenden finden Sie Abfrage erklärt von psql: schnell ein:

EXPLAIN ANALYZE SELECT 
    accounts.id 
FROM "accounts" 
LEFT OUTER JOIN "addresses" 
    ON "addresses"."addressable_id" = "accounts"."id" 
    AND "addresses"."address_type" = 'mailing' 
    AND "addresses"."addressable_type" = 'Account' 
WHERE "accounts"."organization_id" = 16 
AND (addresses.state_code IN ('CA')) 
ORDER BY accounts.name DESC; 
                     QUERY PLAN 
--------------------------------------------------------------------------------------------------------------------------------------------------------- 
Sort (cost=4941.94..4941.94 rows=1 width=18) (actual time=74.810..74.969 rows=821 loops=1) 
    Sort Key: accounts.name 
    Sort Method: quicksort Memory: 75kB 
    -> Hash Join (cost=4.46..4941.93 rows=1 width=18) (actual time=70.044..73.148 rows=821 loops=1) 
     Hash Cond: (addresses.addressable_id = accounts.id) 
     -> Seq Scan on addresses (cost=0.00..4911.93 rows=6806 width=4) (actual time=0.027..65.547 rows=15244 loops=1) 
       Filter: (((address_type)::text = 'mailing'::text) AND ((addressable_type)::text = 'Account'::text) AND ((state_code)::text = 'CA'::text)) 
       Rows Removed by Filter: 129688 
     -> Hash (cost=4.45..4.45 rows=1 width=18) (actual time=2.037..2.037 rows=1775 loops=1) 
       Buckets: 1024 Batches: 1 Memory Usage: 87kB 
       -> Index Scan using organization_id_index on accounts (cost=0.29..4.45 rows=1 width=18) (actual time=0.018..1.318 rows=1775 loops=1) 
        Index Cond: (organization_id = 16) 
Planning time: 0.565 ms 
Execution time: 75.224 ms 
(14 rows) 

langsam ein:

EXPLAIN ANALYZE SELECT 
    accounts.id 
FROM "accounts" 
LEFT OUTER JOIN "addresses" 
    ON "addresses"."addressable_id" = "accounts"."id" 
    AND "addresses"."address_type" = 'mailing' 
    AND "addresses"."addressable_type" = 'Account' 
WHERE "accounts"."organization_id" = 16 
AND (addresses.state_code IN ('NV')) 
ORDER BY accounts.name DESC; 
                     QUERY PLAN 
--------------------------------------------------------------------------------------------------------------------------------------------------------- 
Sort (cost=4917.27..4917.27 rows=1 width=18) (actual time=97091.270..97091.277 rows=25 loops=1) 
    Sort Key: accounts.name 
    Sort Method: quicksort Memory: 26kB 
    -> Nested Loop (cost=0.29..4917.26 rows=1 width=18) (actual time=844.250..97091.083 rows=25 loops=1) 
     Join Filter: (accounts.id = addresses.addressable_id) 
     Rows Removed by Join Filter: 915875 
     -> Index Scan using organization_id_index on accounts (cost=0.29..4.45 rows=1 width=18) (actual time=0.017..10.315 rows=1775 loops=1) 
       Index Cond: (organization_id = 16) 
     -> Seq Scan on addresses (cost=0.00..4911.93 rows=70 width=4) (actual time=0.110..54.521 rows=516 loops=1775) 
       Filter: (((address_type)::text = 'mailing'::text) AND ((addressable_type)::text = 'Account'::text) AND ((state_code)::text = 'NV'::text)) 
       Rows Removed by Filter: 144416 
Planning time: 0.308 ms 
Execution time: 97091.325 ms 
(13 rows) 

langsam ein Ergebnis wird 25 Zeilen, schnell ist 821 Zeilen, das ist noch verwirrender .

+0

Wie viele Zeilen beginnen mit 'C' und wie viele Zeilen beginnen mit 'A'? Können Sie uns auch Ihre Anfrage zeigen? –

+0

@LajosArpad Bearbeitete meine Frage. Ich habe mehr Datensätze mit "C" als mit "A". Es ist auch nicht nur "AZ" die Liste ist viel größer, es ist fast nur "CA", die richtig funktioniert, was mir fremd ist. –

+0

Petya, das ist interessant. Man würde erwarten, dass die Suche nach Kalifornien langsamer ist als die Suche nach Arizona. Hier passiert jedoch etwas anders. Wir können die Reihenfolge als Ursache ausschließen, da die Anzahl der Ergebnisse in beiden Fällen fast identisch ist. Ich frage mich, ob die Auswahlklausel es langsamer macht. Können Sie in beiden Fällen eine einzelne kleine Spalte testen? Wenn Sie das tun, ändert sich das Verhalten? –

Antwort

1

Ich löste es mit VACUUM ANALYZE Befehl aus der Befehlszeile psql.

Verwandte Themen