2010-06-03 8 views
9

Używam Hibernate 3.3.2 w dość dużym projekcie z PostgreSQL 8.4 przy użyciu PostgreSQLDialect.Uzyskiwanie stanu hibernacji w celu wygenerowania indeksów na kluczach obcych

Sposób, w jaki budujemy nasze relacje, kończy się na wyszukiwaniu atrybutów Klucza obcego w naszych tabelach.

Ze względów wydajności chciałbym, aby Hibernate dodawać indeksy do wszystkich kolumn klucza obcego podczas tworzenia naszych tabel przy użyciu hbm2dll.auto.

MySQL automatycznie doda indeksy do tych kolumn, ale nie wydaje się, aby można to było zrobić w Postgresie.

Czy istnieje opcja, którą można ustawić gdzieś, lub coś, co mogę dodać do moich plików hbm.xml, aby tak się stało?

Odpowiedz

2

Hibernacja wymusza tylko indeksowanie dla MySQL, nie dla PostgreSQL, Oracle, itp. MySQL nie zezwala na klucze obce bez indeksu, inne bazy danych nie mają tego ograniczenia.

Sybase ma explanation, dlaczego warto wymuszać indeksy, Hibernate forum ma również temat na ten temat (związany z Oracle), w tym obejścia. Ale zanim zaczniesz tworzyć wiele indeksów, zacznij sprawdzać, czy potrzebujesz wszystkich tych indeksów. W wielu przypadkach indeksy można łączyć z innymi, aby przyspieszyć działanie. To wszystko zależy!

Zastosowanie Wyjaśnij na swoje pytania, w jaki sposób baza danych wykonuje je, co indeksy są używane, gdzie indeksy brakuje itp

+4

To ma sens, aby nie * wymuszać * kluczy obcych do indeksu, ale wydaje się, że byłoby to dobre Opcja zezwolenia: – biggusjimmus

1

Spróbuj jednego z:

<many-to-one name="master" class="Master" column="master_id" index="my_index_name" /> 

<many-to-one name="master" class="Master"> 
    <column name="master_id" index="my_index_name" /> 
</many-to-one> 
+0

Próbowałem obu tych, ale przeszukiwanie bazy danych dla indeksów, które powinny zostać utworzone, nie daje żadnych wyników = \ Nie jestem pewien, co robię źle, ale nadal będę się do niego podłączać – biggusjimmus

+0

Jakie są ustawienia używasz go z? Być może nie są one dodawane z "aktualizacja", ale byłoby z "create" lub "create-drop"? Inny pomysł, może to być błąd podobny do tego: http: //opensource.atlassian. com/projects/hibernate/browse/HHH-1012 –

2

oto szybkie-i- dirty query które generuje DDL dla indeksów na każdego zdefiniowanego klucza obcego w schemacie:

SELECT 'CREATE INDEX fk_' || conname || '_idx ON ' 
     || relname || ' ' || 
     regexp_replace(
      regexp_replace(pg_get_constraintdef(pg_constraint.oid, true), 
      ' REFERENCES.*$','',''), 'FOREIGN KEY ','','') || ';' 
FROM pg_constraint 
JOIN pg_class 
    ON (conrelid = pg_class.oid) 
JOIN pg_namespace 
    ON (relnamespace = pg_namespace.oid) 
WHERE contype = 'f' 
    AND nspname = 'public'; 

to tylko został przetestowany w PostgreSQL 8.4, ale myślę, że to powinno działać w większości Vers 8.x. jony.

Należy również pamiętać, że nie wykrywa, które z nich są już objęte indeksem, więc prawdopodobnie będziesz mieć duplikację.

+0

Gdy baza danych jest skonfigurowana, jest to pomocne, ale na to pytanie byłem bardziej zainteresowany uzyskaniem hibernacji, aby zrobić to dla mnie, gdy tworzy tabele. Jest to świetna odpowiedź na moje inne powiązane pytanie: http: // stackoverflow.com/questions/2970050/postgresql-how-to-index-all-foreign-keys – biggusjimmus

+0

Myślę, że to nie działa na cytowanych nazwanych zmiennych. –

+0

@Ravshan: Ignorowanie w momencie, w którym nie należy używać nazw cytowanych w definicjach tabel bazy danych, wydaje się działać dla mnie w 9.3: wybierz odrębne regexp_replace (regexp_replace (pg_get_constraintdef (oid), '^. * REFERENCJE', 'CREATE INDEX ON '),' \). * $ ','); ') Od pg_constraint gdzie contype =' f '. –

-1

Oprócz odpowiedź Mateusza: Dodawanie

AND NOT EXISTS (
    SELECT * FROM pg_class pgc 
    JOIN pg_namespace pgn ON (pgc.relnamespace = pgn.oid) 
    WHERE relkind='i' 
    AND pgc.relname = ('fk_' || conname || '_idx')) 

tuż przed średnik tworzy tylko indeksów, jeśli nie istnieje. Pozwala to na wielokrotne wykonywanie instrukcji bez tworzenia "relacji fk _..." już istnieje "błędy

Powiązane problemy