Ein kleine Lektion über Datenbank-Performance

Kategorie Webentwicklung
Inhalt
Was mag wohl schneller sein? Version 1:
     SELECT element_id
       FROM matches 
       JOIN objects ON object_id=element_id
      WHERE parent_id IN($pids) AND inactive=0
      ORDER BY create_date DESC
oder Version 2:
           SELECT object_id
             FROM objects
            WHERE object_id IN
               (
                   SELECT element_id
                     FROM matches
                     WHERE parent_id IN ($pids)
               )
              AND inactive=0
            ORDER BY create_date DESC

Die Fragestellung sagt schon, beide waren nicht gleich schnell, obwohl sie dasselbe tun.
Version 1 braucht 400 Millisekunden, Version 2 braucht 100 Millisekunden.

Das Problem in ersterem Fall war ein Table Scan auf der objects-Tabelle, um festzustellen, wo inactive=0 ist. Wieso der PostgresQL-Optimizer auf die Idee kam anzunehmen, daß er die Tabelle komplett durchsuchen müsse, kann ich mir nicht so recht erklären, immerhin beschränkt der andere Teil der WHERE-Bedingung die Zahl der Ergebnisse auf 20000 von 800000.
Ach, und natürlich liegt auf inactive ein Index, aber der ist ziemlich oft eher nutzlos (gerade mal 10000 Einträge haben da einen Wert <> 0).

Nun optimiere ich also für den Optimizer... das wird sich bestimmt irgendwann rächen.
Diashow
Blog