让Hibernate在外键上生成索引

时间:2010-06-03 22:17:48

标签: hibernate postgresql indexing foreign-keys

我在使用PostgreSQLDialect的PostgreSQL 8.4的一个相当大的项目中使用Hibernate 3.3.2。

我们建立关系的方式,最终我们对表的外键属性进行了大量搜索。

出于性能原因,我希望Hibernate在使用hbm2dll.auto创建表时为所有外键列添加索引。

MySQL会自动为这些列添加索引,但似乎没有办法在Postgres中执行此操作。

我可以在某个地方设置一个选项,或者我可以添加到我的hbm.xml文件中以实现此目的吗?

4 个答案:

答案 0 :(得分:2)

Hibernate只强制执行MySQL的索引创建,而不是PostgreSQL,Oracle等.MySQL不允许没有索引的外键,其他数据库没有这个限制。

Sybase有一个explanation为什么不执行索引是一件好事,Hibernate forum也有一个关于它的主题(与Oracle相关),包括一个解决方法。但在开始创建大量索引之前,请开始检查是否需要所有这些索引。在许多情况下,索引可以与其他索引相结合以加快速度。这完全取决于!

对查询使用EXPLAIN以查看数据库如何执行它们,使用哪些索引,缺少索引的位置等。

答案 1 :(得分:2)

这是一个快速而肮脏的查询,它将为模式中每个定义的外键的索引生成DDL:

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';

这只在PostgreSQL 8.4中测试过,但我认为它应该适用于大多数8.x版本。

另请注意,这不会检测索引已涵盖哪些索引,因此您可能会有一些重复。

答案 2 :(得分:1)

尝试以下任一方式:

<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>

答案 3 :(得分:0)

除了马修的回答: 添加

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') )
分号之前的

只在不存在的情况下才创建索引。这允许您重复执行语句而不产生“关系fk _...”已存在“错误。